diff --git a/Cargo.lock b/Cargo.lock index 03dc7890d5..c7c465291d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2606,6 +2606,7 @@ dependencies = [ name = "nu-cmd-extra" version = "0.83.2" dependencies = [ + "Inflector", "ahash", "fancy-regex", "htmlescape", @@ -2657,7 +2658,6 @@ dependencies = [ name = "nu-command" version = "0.83.2" dependencies = [ - "Inflector", "alphanumeric-sort", "base64", "bracoxide", diff --git a/crates/nu-cmd-extra/Cargo.toml b/crates/nu-cmd-extra/Cargo.toml index 9f2650c449..851e186198 100644 --- a/crates/nu-cmd-extra/Cargo.toml +++ b/crates/nu-cmd-extra/Cargo.toml @@ -20,6 +20,7 @@ nu-cmd-base = { path = "../nu-cmd-base", version = "0.83.2" } nu-utils = { path = "../nu-utils", version = "0.83.2" } # Potential dependencies for extras +Inflector = "0.11" num-traits = "0.2" ahash = "0.8.3" nu-ansi-term = "0.49.0" diff --git a/crates/nu-cmd-extra/src/extra/mod.rs b/crates/nu-cmd-extra/src/extra/mod.rs index fc69f76b45..a4a855a101 100644 --- a/crates/nu-cmd-extra/src/extra/mod.rs +++ b/crates/nu-cmd-extra/src/extra/mod.rs @@ -88,7 +88,14 @@ pub fn add_extra_command_context(mut engine_state: EngineState) -> EngineState { strings::format::FileSize, strings::format::FormatDuration, strings::encode_decode::EncodeHex, - strings::encode_decode::DecodeHex + strings::encode_decode::DecodeHex, + strings::str_::case::Str, + strings::str_::case::StrCamelCase, + strings::str_::case::StrKebabCase, + strings::str_::case::StrPascalCase, + strings::str_::case::StrScreamingSnakeCase, + strings::str_::case::StrSnakeCase, + strings::str_::case::StrTitleCase ); bind_command!(formats::ToHtml, formats::FromUrl); diff --git a/crates/nu-cmd-extra/src/extra/strings/mod.rs b/crates/nu-cmd-extra/src/extra/strings/mod.rs index 0de3959dee..391cf108e0 100644 --- a/crates/nu-cmd-extra/src/extra/strings/mod.rs +++ b/crates/nu-cmd-extra/src/extra/strings/mod.rs @@ -1,2 +1,3 @@ pub(crate) mod encode_decode; pub(crate) mod format; +pub(crate) mod str_; diff --git a/crates/nu-command/src/strings/str_/case/camel_case.rs b/crates/nu-cmd-extra/src/extra/strings/str_/case/camel_case.rs similarity index 99% rename from crates/nu-command/src/strings/str_/case/camel_case.rs rename to crates/nu-cmd-extra/src/extra/strings/str_/case/camel_case.rs index 725ee2ce8a..e23bddbcad 100644 --- a/crates/nu-command/src/strings/str_/case/camel_case.rs +++ b/crates/nu-cmd-extra/src/extra/strings/str_/case/camel_case.rs @@ -5,7 +5,7 @@ use nu_protocol::{ Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; -use crate::operate; +use super::operate; #[derive(Clone)] pub struct SubCommand; diff --git a/crates/nu-command/src/strings/str_/case/kebab_case.rs b/crates/nu-cmd-extra/src/extra/strings/str_/case/kebab_case.rs similarity index 99% rename from crates/nu-command/src/strings/str_/case/kebab_case.rs rename to crates/nu-cmd-extra/src/extra/strings/str_/case/kebab_case.rs index b33fe24143..fdf0fb81d9 100644 --- a/crates/nu-command/src/strings/str_/case/kebab_case.rs +++ b/crates/nu-cmd-extra/src/extra/strings/str_/case/kebab_case.rs @@ -5,7 +5,7 @@ use nu_protocol::{ Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; -use crate::operate; +use super::operate; #[derive(Clone)] pub struct SubCommand; diff --git a/crates/nu-cmd-extra/src/extra/strings/str_/case/mod.rs b/crates/nu-cmd-extra/src/extra/strings/str_/case/mod.rs new file mode 100644 index 0000000000..dac550c4d7 --- /dev/null +++ b/crates/nu-cmd-extra/src/extra/strings/str_/case/mod.rs @@ -0,0 +1,74 @@ +mod camel_case; +mod kebab_case; +mod pascal_case; +mod screaming_snake_case; +mod snake_case; +mod str_; +mod title_case; + +pub use camel_case::SubCommand as StrCamelCase; +pub use kebab_case::SubCommand as StrKebabCase; +pub use pascal_case::SubCommand as StrPascalCase; +pub use screaming_snake_case::SubCommand as StrScreamingSnakeCase; +pub use snake_case::SubCommand as StrSnakeCase; +pub use str_::Str; +pub use title_case::SubCommand as StrTitleCase; + +use nu_engine::CallExt; + +use nu_cmd_base::input_handler::{operate as general_operate, CmdArgument}; +use nu_protocol::ast::{Call, CellPath}; +use nu_protocol::engine::{EngineState, Stack}; +use nu_protocol::{PipelineData, ShellError, Span, Value}; + +struct Arguments String + Send + Sync + 'static> { + case_operation: &'static F, + cell_paths: Option>, +} + +impl String + Send + Sync + 'static> CmdArgument for Arguments { + fn take_cell_paths(&mut self) -> Option> { + self.cell_paths.take() + } +} + +pub fn operate( + engine_state: &EngineState, + stack: &mut Stack, + call: &Call, + input: PipelineData, + case_operation: &'static F, +) -> Result +where + F: Fn(&str) -> String + Send + Sync + 'static, +{ + let cell_paths: Vec = call.rest(engine_state, stack, 0)?; + let cell_paths = (!cell_paths.is_empty()).then_some(cell_paths); + let args = Arguments { + case_operation, + cell_paths, + }; + general_operate(action, args, input, call.head, engine_state.ctrlc.clone()) +} + +fn action(input: &Value, args: &Arguments, head: Span) -> Value +where + F: Fn(&str) -> String + Send + Sync + 'static, +{ + let case_operation = args.case_operation; + match input { + Value::String { val, .. } => Value::String { + val: case_operation(val), + span: head, + }, + Value::Error { .. } => input.clone(), + _ => Value::Error { + error: Box::new(ShellError::OnlySupportsThisInputType { + exp_input_type: "string".into(), + wrong_type: input.get_type().to_string(), + dst_span: head, + src_span: input.expect_span(), + }), + }, + } +} diff --git a/crates/nu-command/src/strings/str_/case/pascal_case.rs b/crates/nu-cmd-extra/src/extra/strings/str_/case/pascal_case.rs similarity index 99% rename from crates/nu-command/src/strings/str_/case/pascal_case.rs rename to crates/nu-cmd-extra/src/extra/strings/str_/case/pascal_case.rs index 29bfa974b9..b7517ae6f9 100644 --- a/crates/nu-command/src/strings/str_/case/pascal_case.rs +++ b/crates/nu-cmd-extra/src/extra/strings/str_/case/pascal_case.rs @@ -5,7 +5,7 @@ use nu_protocol::{ Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; -use crate::operate; +use super::operate; #[derive(Clone)] pub struct SubCommand; diff --git a/crates/nu-command/src/strings/str_/case/screaming_snake_case.rs b/crates/nu-cmd-extra/src/extra/strings/str_/case/screaming_snake_case.rs similarity index 99% rename from crates/nu-command/src/strings/str_/case/screaming_snake_case.rs rename to crates/nu-cmd-extra/src/extra/strings/str_/case/screaming_snake_case.rs index 97dea22778..082b0a3e9f 100644 --- a/crates/nu-command/src/strings/str_/case/screaming_snake_case.rs +++ b/crates/nu-cmd-extra/src/extra/strings/str_/case/screaming_snake_case.rs @@ -5,7 +5,8 @@ use nu_protocol::{ Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; -use crate::operate; +use super::operate; + #[derive(Clone)] pub struct SubCommand; diff --git a/crates/nu-command/src/strings/str_/case/snake_case.rs b/crates/nu-cmd-extra/src/extra/strings/str_/case/snake_case.rs similarity index 99% rename from crates/nu-command/src/strings/str_/case/snake_case.rs rename to crates/nu-cmd-extra/src/extra/strings/str_/case/snake_case.rs index 16b3bd977e..bd0c67494d 100644 --- a/crates/nu-command/src/strings/str_/case/snake_case.rs +++ b/crates/nu-cmd-extra/src/extra/strings/str_/case/snake_case.rs @@ -5,7 +5,7 @@ use nu_protocol::{ Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; -use crate::operate; +use super::operate; #[derive(Clone)] pub struct SubCommand; diff --git a/crates/nu-cmd-extra/src/extra/strings/str_/case/str_.rs b/crates/nu-cmd-extra/src/extra/strings/str_/case/str_.rs new file mode 100644 index 0000000000..6cfd59b715 --- /dev/null +++ b/crates/nu-cmd-extra/src/extra/strings/str_/case/str_.rs @@ -0,0 +1,49 @@ +use nu_engine::get_full_help; +use nu_protocol::{ + ast::Call, + engine::{Command, EngineState, Stack}, + Category, IntoPipelineData, PipelineData, ShellError, Signature, Type, Value, +}; + +#[derive(Clone)] +pub struct Str; + +impl Command for Str { + fn name(&self) -> &str { + "str" + } + + fn signature(&self) -> Signature { + Signature::build("str") + .category(Category::Strings) + .input_output_types(vec![(Type::Nothing, Type::String)]) + } + + fn usage(&self) -> &str { + "Various commands for working with string data." + } + + fn extra_usage(&self) -> &str { + "You must use one of the following subcommands. Using this command as-is will only produce this help message." + } + + fn run( + &self, + engine_state: &EngineState, + stack: &mut Stack, + call: &Call, + _input: PipelineData, + ) -> Result { + Ok(Value::String { + val: get_full_help( + &Str.signature(), + &Str.examples(), + engine_state, + stack, + self.is_parser_keyword(), + ), + span: call.head, + } + .into_pipeline_data()) + } +} diff --git a/crates/nu-command/src/strings/str_/case/title_case.rs b/crates/nu-cmd-extra/src/extra/strings/str_/case/title_case.rs similarity index 99% rename from crates/nu-command/src/strings/str_/case/title_case.rs rename to crates/nu-cmd-extra/src/extra/strings/str_/case/title_case.rs index 67968ae012..7d102e51b9 100644 --- a/crates/nu-command/src/strings/str_/case/title_case.rs +++ b/crates/nu-cmd-extra/src/extra/strings/str_/case/title_case.rs @@ -5,7 +5,7 @@ use nu_protocol::{ Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; -use crate::operate; +use super::operate; #[derive(Clone)] pub struct SubCommand; diff --git a/crates/nu-cmd-extra/src/extra/strings/str_/mod.rs b/crates/nu-cmd-extra/src/extra/strings/str_/mod.rs new file mode 100644 index 0000000000..61fccfff69 --- /dev/null +++ b/crates/nu-cmd-extra/src/extra/strings/str_/mod.rs @@ -0,0 +1,3 @@ +pub(crate) mod case; + +pub use case::*; diff --git a/crates/nu-command/Cargo.toml b/crates/nu-command/Cargo.toml index b8b2cd3dca..6260649a9a 100644 --- a/crates/nu-command/Cargo.toml +++ b/crates/nu-command/Cargo.toml @@ -28,7 +28,6 @@ nu-table = { path = "../nu-table", version = "0.83.2" } nu-term-grid = { path = "../nu-term-grid", version = "0.83.2" } nu-utils = { path = "../nu-utils", version = "0.83.2" } -Inflector = "0.11" alphanumeric-sort = "1.5" base64 = "0.21" byteorder = "1.4" diff --git a/crates/nu-command/src/default_context.rs b/crates/nu-command/src/default_context.rs index 1c39988178..54a4041051 100644 --- a/crates/nu-command/src/default_context.rs +++ b/crates/nu-command/src/default_context.rs @@ -177,7 +177,6 @@ pub fn add_shell_command_context(mut engine_state: EngineState) -> EngineState { SplitRow, SplitWords, Str, - StrCamelCase, StrCapitalize, StrContains, StrDistance, @@ -187,16 +186,11 @@ pub fn add_shell_command_context(mut engine_state: EngineState) -> EngineState { StrJoin, StrReplace, StrIndexOf, - StrKebabCase, StrLength, - StrPascalCase, StrReverse, - StrScreamingSnakeCase, - StrSnakeCase, StrStartsWith, StrSubstring, StrTrim, - StrTitleCase, StrUpcase, FormatDate }; diff --git a/crates/nu-command/src/strings/str_/case/mod.rs b/crates/nu-command/src/strings/str_/case/mod.rs index 0df18ec78f..2aa35e981b 100644 --- a/crates/nu-command/src/strings/str_/case/mod.rs +++ b/crates/nu-command/src/strings/str_/case/mod.rs @@ -1,23 +1,11 @@ -mod camel_case; mod capitalize; mod downcase; -mod kebab_case; -mod pascal_case; -mod screaming_snake_case; -mod snake_case; mod str_; -mod title_case; mod upcase; -pub use camel_case::SubCommand as StrCamelCase; pub use capitalize::SubCommand as StrCapitalize; pub use downcase::SubCommand as StrDowncase; -pub use kebab_case::SubCommand as StrKebabCase; -pub use pascal_case::SubCommand as StrPascalCase; -pub use screaming_snake_case::SubCommand as StrScreamingSnakeCase; -pub use snake_case::SubCommand as StrSnakeCase; pub use str_::Str; -pub use title_case::SubCommand as StrTitleCase; pub use upcase::SubCommand as StrUpcase; use nu_engine::CallExt; diff --git a/crates/nu-command/tests/commands/str_/mod.rs b/crates/nu-command/tests/commands/str_/mod.rs index f3d7204864..fe3b0aa015 100644 --- a/crates/nu-command/tests/commands/str_/mod.rs +++ b/crates/nu-command/tests/commands/str_/mod.rs @@ -97,6 +97,7 @@ fn upcases() { } #[test] +#[ignore = "Playgrounds are not supported in nu-cmd-extra"] fn camelcases() { Playground::setup("str_test_3", |dirs, sandbox| { sandbox.with_files(vec![FileWithContent(