diff --git a/crates/nu-cli/src/cli.rs b/crates/nu-cli/src/cli.rs index a172e2d33f..10e049857e 100644 --- a/crates/nu-cli/src/cli.rs +++ b/crates/nu-cli/src/cli.rs @@ -366,6 +366,7 @@ pub fn create_default_context( whole_stream_command(Get), whole_stream_command(Update), whole_stream_command(Insert), + whole_stream_command(IntoInt), whole_stream_command(SplitBy), // Row manipulation whole_stream_command(Reverse), diff --git a/crates/nu-cli/src/commands.rs b/crates/nu-cli/src/commands.rs index 50f8c5ca85..77e62959e9 100644 --- a/crates/nu-cli/src/commands.rs +++ b/crates/nu-cli/src/commands.rs @@ -63,6 +63,7 @@ pub(crate) mod histogram; pub(crate) mod history; pub(crate) mod if_; pub(crate) mod insert; +pub(crate) mod into_int; pub(crate) mod is_empty; pub(crate) mod keep; pub(crate) mod last; @@ -192,6 +193,7 @@ pub(crate) use help::Help; pub(crate) use histogram::Histogram; pub(crate) use history::History; pub(crate) use insert::Insert; +pub(crate) use into_int::IntoInt; pub(crate) use keep::{Keep, KeepUntil, KeepWhile}; pub(crate) use last::Last; pub(crate) use lines::Lines; diff --git a/crates/nu-cli/src/commands/into_int.rs b/crates/nu-cli/src/commands/into_int.rs new file mode 100644 index 0000000000..24db82f440 --- /dev/null +++ b/crates/nu-cli/src/commands/into_int.rs @@ -0,0 +1,88 @@ +use crate::commands::WholeStreamCommand; +use crate::prelude::*; +use nu_errors::ShellError; +use nu_protocol::{Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value}; + +use num_bigint::ToBigInt; + +pub struct IntoInt; + +#[derive(Deserialize)] +pub struct IntoIntArgs { + pub rest: Vec, +} + +#[async_trait] +impl WholeStreamCommand for IntoInt { + fn name(&self) -> &str { + "into-int" + } + + fn signature(&self) -> Signature { + Signature::build("into-int").rest(SyntaxShape::Any, "the values to into-int") + } + + fn usage(&self) -> &str { + "Convert value to integer" + } + + async fn run( + &self, + args: CommandArgs, + registry: &CommandRegistry, + ) -> Result { + into_int(args, registry).await + } + + fn examples(&self) -> Vec { + vec![Example { + description: "Convert filesize to integer", + example: "echo 1kb | into-int $it | = $it / 1024", + result: Some(vec![UntaggedValue::int(1).into()]), + }] + } +} + +async fn into_int( + args: CommandArgs, + registry: &CommandRegistry, +) -> Result { + let registry = registry.clone(); + let (args, _): (IntoIntArgs, _) = args.process(®istry).await?; + + let stream = args.rest.into_iter().map(|i| match i { + Value { + value: UntaggedValue::Primitive(primitive_val), + tag, + } => match primitive_val { + Primitive::Filesize(size) => OutputStream::one(Ok(ReturnSuccess::Value(Value { + value: UntaggedValue::int(size.to_bigint().expect("Conversion should never fail.")), + tag, + }))), + Primitive::Int(_) => OutputStream::one(Ok(ReturnSuccess::Value(Value { + value: UntaggedValue::Primitive(primitive_val), + tag, + }))), + _ => OutputStream::one(Err(ShellError::labeled_error( + "Could not convert int value", + "original value", + tag, + ))), + }, + _ => OutputStream::one(Ok(ReturnSuccess::Value(i))), + }); + + Ok(futures::stream::iter(stream).flatten().to_output_stream()) +} + +#[cfg(test)] +mod tests { + use super::IntoInt; + + #[test] + fn examples_work_as_expected() { + use crate::examples::test as test_examples; + + test_examples(IntoInt {}) + } +} diff --git a/crates/nu-cli/src/examples.rs b/crates/nu-cli/src/examples.rs index 916606aafa..dc86007f02 100644 --- a/crates/nu-cli/src/examples.rs +++ b/crates/nu-cli/src/examples.rs @@ -6,7 +6,7 @@ use nu_protocol::hir::ClassifiedBlock; use nu_protocol::{ShellTypeName, Value}; use crate::commands::classified::block::run_block; -use crate::commands::{whole_stream_command, BuildString, Echo, StrCollect}; +use crate::commands::{whole_stream_command, BuildString, Each, Echo, StrCollect}; use crate::context::Context; use crate::stream::InputStream; use crate::WholeStreamCommand; @@ -18,6 +18,7 @@ pub fn test(cmd: impl WholeStreamCommand + 'static) { base_context.add_commands(vec![ whole_stream_command(Echo {}), whole_stream_command(BuildString {}), + whole_stream_command(Each {}), whole_stream_command(cmd), whole_stream_command(StrCollect), ]); diff --git a/crates/nu-cli/tests/commands/into_int.rs b/crates/nu-cli/tests/commands/into_int.rs new file mode 100644 index 0000000000..47dc71c383 --- /dev/null +++ b/crates/nu-cli/tests/commands/into_int.rs @@ -0,0 +1,25 @@ +use nu_test_support::{nu, pipeline}; + +#[test] +fn into_int_filesize() { + let actual = nu!( + cwd: ".", pipeline( + r#" + into-int 1kb | = $it / 1024 + "# + )); + + assert!(actual.out.contains("1")); +} + +#[test] +fn into_int_int() { + let actual = nu!( + cwd: ".", pipeline( + r#" + into-int 1024 | = $it / 1024 + "# + )); + + assert!(actual.out.contains("1")); +} diff --git a/crates/nu-cli/tests/commands/mod.rs b/crates/nu-cli/tests/commands/mod.rs index 9e1142c763..f29e7c8906 100644 --- a/crates/nu-cli/tests/commands/mod.rs +++ b/crates/nu-cli/tests/commands/mod.rs @@ -21,6 +21,7 @@ mod group_by; mod headers; mod histogram; mod insert; +mod into_int; mod is_empty; mod keep; mod last;