Add str collect (#311)

* Add str collect

* Oops, missing file
This commit is contained in:
JT 2021-11-09 14:59:44 +13:00 committed by GitHub
parent ce714f098f
commit 47628946b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 117 additions and 18 deletions

View File

@ -25,7 +25,6 @@ pub fn create_default_context() -> EngineState {
Alias,
Benchmark,
BuildString,
CamelCase,
Cd,
Collect,
Cp,
@ -49,7 +48,6 @@ pub fn create_default_context() -> EngineState {
FromJson,
Get,
Griddle,
KebabCase,
Help,
Hide,
If,
@ -83,7 +81,6 @@ pub fn create_default_context() -> EngineState {
Mkdir,
Module,
Mv,
PascalCase,
ParEach,
Ps,
Range,
@ -92,12 +89,17 @@ pub fn create_default_context() -> EngineState {
Select,
Shuffle,
Size,
ScreamingSnakeCase,
SnakeCase,
Split,
SplitChars,
SplitColumn,
SplitRow,
Str,
StrCamelCase,
StrCollect,
StrKebabCase,
StrPascalCase,
StrScreamingSnakeCase,
StrSnakeCase,
Sys,
Table,
To,

View File

@ -7,7 +7,7 @@ use nu_protocol::{
use crate::To;
use super::{Case, Date, From, Into, Math, Split};
use super::{Date, From, Into, Math, Split, Str};
pub fn test_examples(cmd: impl Command + 'static) {
let examples = cmd.examples();
@ -17,7 +17,7 @@ pub fn test_examples(cmd: impl Command + 'static) {
// Base functions that are needed for testing
// Try to keep this working set small to keep tests running as fast as possible
let mut working_set = StateWorkingSet::new(&*engine_state);
working_set.add_decl(Box::new(Case));
working_set.add_decl(Box::new(Str));
working_set.add_decl(Box::new(From));
working_set.add_decl(Box::new(To));
working_set.add_decl(Box::new(Into));

View File

@ -6,9 +6,9 @@ use nu_protocol::{
};
#[derive(Clone)]
pub struct Case;
pub struct Str;
impl Command for Case {
impl Command for Str {
fn name(&self) -> &str {
"str"
}
@ -18,7 +18,7 @@ impl Command for Case {
}
fn usage(&self) -> &str {
"Converts strings into different kind of cases: camel, kebab, pascal, snake, and screaming snake."
"Various commands for working with string data."
}
fn run(
@ -29,7 +29,7 @@ impl Command for Case {
_input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
Ok(Value::String {
val: get_full_help(&Case.signature(), &Case.examples(), engine_state),
val: get_full_help(&Str.signature(), &Str.examples(), engine_state),
span: call.head,
}
.into_pipeline_data())
@ -44,6 +44,6 @@ mod test {
fn test_examples() {
use crate::test_examples;
test_examples(Case {})
test_examples(Str {})
}
}

View File

@ -5,12 +5,12 @@ pub mod pascal_case;
pub mod screaming_snake_case;
pub mod snake_case;
pub use camel_case::SubCommand as CamelCase;
pub use command::Case;
pub use kebab_case::SubCommand as KebabCase;
pub use pascal_case::SubCommand as PascalCase;
pub use screaming_snake_case::SubCommand as ScreamingSnakeCase;
pub use snake_case::SubCommand as SnakeCase;
pub use camel_case::SubCommand as StrCamelCase;
pub use command::Str;
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;
use nu_engine::CallExt;

View File

@ -0,0 +1,95 @@
use nu_engine::CallExt;
use nu_protocol::ast::Call;
use nu_protocol::engine::{Command, EngineState, Stack};
use nu_protocol::{
Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
};
#[derive(Clone)]
pub struct StrCollect;
impl Command for StrCollect {
fn name(&self) -> &str {
"str collect"
}
fn signature(&self) -> Signature {
Signature::build("str collect").optional(
"separator",
SyntaxShape::String,
"optional separator to use when creating string",
)
}
fn usage(&self) -> &str {
"creates a string from the input, optionally using a separator"
}
fn run(
&self,
engine_state: &EngineState,
stack: &mut Stack,
call: &Call,
input: PipelineData,
) -> Result<PipelineData, ShellError> {
let separator: Option<String> = call.opt(engine_state, stack, 0)?;
#[allow(clippy::needless_collect)]
let strings: Vec<Result<String, ShellError>> =
input.into_iter().map(|value| value.as_string()).collect();
let strings: Result<Vec<_>, _> = strings.into_iter().collect::<Result<_, _>>();
match strings {
Ok(strings) => {
let output = if let Some(separator) = separator {
strings.join(&separator)
} else {
strings.join("")
};
Ok(Value::String {
val: output,
span: call.head,
}
.into_pipeline_data())
}
_ => Err(ShellError::CantConvert(
"string".into(),
"non-string input".into(),
call.head,
)),
}
}
fn examples(&self) -> Vec<Example> {
vec![
Example {
description: "Create a string from input",
example: "['nu', 'shell'] | str collect",
result: Some(Value::String {
val: "nushell".to_string(),
span: Span::unknown(),
}),
},
Example {
description: "Create a string from input with a separator",
example: "['nu', 'shell'] | str collect '-'",
result: Some(Value::String {
val: "nu-shell".to_string(),
span: Span::unknown(),
}),
},
]
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_examples() {
use crate::test_examples;
test_examples(StrCollect {})
}
}

View File

@ -1,3 +1,5 @@
mod case;
mod collect;
pub use case::*;
pub use collect::*;