diff --git a/crates/nu-command/src/default_context.rs b/crates/nu-command/src/default_context.rs index b1ba99470b..64b68f19dd 100644 --- a/crates/nu-command/src/default_context.rs +++ b/crates/nu-command/src/default_context.rs @@ -48,6 +48,8 @@ pub fn create_default_context() -> EngineState { LetEnv, Lines, Ls, + Math, + MathAbs, Mkdir, Module, Mv, diff --git a/crates/nu-command/src/example_test.rs b/crates/nu-command/src/example_test.rs index c7ca4f0011..3685af3996 100644 --- a/crates/nu-command/src/example_test.rs +++ b/crates/nu-command/src/example_test.rs @@ -5,7 +5,7 @@ use nu_protocol::{ PipelineData, }; -use super::{From, Into, Split}; +use super::{From, Into, Math, Split}; pub fn test_examples(cmd: impl Command + 'static) { let examples = cmd.examples(); @@ -18,6 +18,7 @@ pub fn test_examples(cmd: impl Command + 'static) { working_set.add_decl(Box::new(From)); working_set.add_decl(Box::new(Into)); working_set.add_decl(Box::new(Split)); + working_set.add_decl(Box::new(Math)); // Adding the command that is being tested to the working set working_set.add_decl(Box::new(cmd)); diff --git a/crates/nu-command/src/lib.rs b/crates/nu-command/src/lib.rs index 4e0f0a7f46..151c6076cf 100644 --- a/crates/nu-command/src/lib.rs +++ b/crates/nu-command/src/lib.rs @@ -7,6 +7,7 @@ mod experimental; mod filesystem; mod filters; mod formats; +mod math; mod strings; mod system; mod viewers; @@ -20,6 +21,7 @@ pub use experimental::*; pub use filesystem::*; pub use filters::*; pub use formats::*; +pub use math::*; pub use strings::*; pub use system::*; pub use viewers::*; diff --git a/crates/nu-command/src/math/abs.rs b/crates/nu-command/src/math/abs.rs new file mode 100644 index 0000000000..95f46ef7ad --- /dev/null +++ b/crates/nu-command/src/math/abs.rs @@ -0,0 +1,81 @@ +use nu_protocol::ast::Call; +use nu_protocol::engine::{Command, EngineState, Stack}; +use nu_protocol::{Example, PipelineData, ShellError, Signature, Span, Value}; + +#[derive(Clone)] +pub struct SubCommand; + +impl Command for SubCommand { + fn name(&self) -> &str { + "math abs" + } + + fn signature(&self) -> Signature { + Signature::build("math abs") + } + + fn usage(&self) -> &str { + "Returns absolute values of a list of numbers" + } + + fn run( + &self, + _engine_state: &EngineState, + _stack: &mut Stack, + call: &Call, + input: PipelineData, + ) -> Result { + let head = call.head; + input.map(move |value| abs_helper(value, head)) + } + + fn examples(&self) -> Vec { + vec![Example { + description: "Get absolute of each value in a list of numbers", + example: "[-50 -100.0 25] | math abs", + result: Some(Value::List { + vals: vec![ + Value::test_int(50), + Value::Float { + val: 100.0, + span: Span::unknown(), + }, + Value::test_int(25), + ], + span: Span::unknown(), + }), + }] + } +} + +fn abs_helper(val: Value, head: Span) -> Value { + match val { + Value::Int { val, span } => Value::int(val.abs(), span), + Value::Float { val, span } => Value::Float { + val: val.abs(), + span, + }, + Value::Duration { val, span } => Value::Duration { + val: val.abs(), + span, + }, + _ => Value::Error { + error: ShellError::UnsupportedInput( + String::from("Only numerical values are supported"), + head, + ), + }, + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_examples() { + use crate::test_examples; + + test_examples(SubCommand {}) + } +} diff --git a/crates/nu-command/src/math/command.rs b/crates/nu-command/src/math/command.rs new file mode 100644 index 0000000000..6efc11f87c --- /dev/null +++ b/crates/nu-command/src/math/command.rs @@ -0,0 +1,41 @@ +use nu_engine::get_full_help; +use nu_protocol::{ + ast::Call, + engine::{Command, EngineState, Stack}, + IntoPipelineData, PipelineData, Signature, Value, +}; + +#[derive(Clone)] +pub struct MathCommand; + +impl Command for MathCommand { + fn name(&self) -> &str { + "math" + } + + fn signature(&self) -> Signature { + Signature::build("math") + } + + fn usage(&self) -> &str { + "Use mathematical functions as aggregate functions on a list of numbers or tables." + } + + fn run( + &self, + engine_state: &EngineState, + _stack: &mut Stack, + call: &Call, + _input: PipelineData, + ) -> Result { + Ok(Value::String { + val: get_full_help( + &MathCommand.signature(), + &MathCommand.examples(), + engine_state, + ), + span: call.head, + } + .into_pipeline_data()) + } +} diff --git a/crates/nu-command/src/math/mod.rs b/crates/nu-command/src/math/mod.rs new file mode 100644 index 0000000000..5abb051b23 --- /dev/null +++ b/crates/nu-command/src/math/mod.rs @@ -0,0 +1,5 @@ +mod abs; +pub mod command; + +pub use abs::SubCommand as MathAbs; +pub use command::MathCommand as Math;