diff --git a/crates/nu-command/src/default_context.rs b/crates/nu-command/src/default_context.rs index 428caa5607..5f9f6d4eb4 100644 --- a/crates/nu-command/src/default_context.rs +++ b/crates/nu-command/src/default_context.rs @@ -62,6 +62,7 @@ pub fn create_default_context() -> EngineState { Math, MathAbs, MathAvg, + MathCeil, MathFloor, MathMax, MathMin, diff --git a/crates/nu-command/src/math/ceil.rs b/crates/nu-command/src/math/ceil.rs new file mode 100644 index 0000000000..a23720ffbe --- /dev/null +++ b/crates/nu-command/src/math/ceil.rs @@ -0,0 +1,73 @@ +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 ceil" + } + + fn signature(&self) -> Signature { + Signature::build("math ceil") + } + + fn usage(&self) -> &str { + "Applies the ceil function to 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| operate(value, head), + engine_state.ctrlc.clone(), + ) + } + + fn examples(&self) -> Vec { + vec![Example { + description: "Apply the ceil function to a list of numbers", + example: "[1.5 2.3 -3.1] | math ceil", + result: Some(Value::List { + vals: vec![Value::test_int(2), Value::test_int(3), Value::test_int(-3)], + span: Span::unknown(), + }), + }] + } +} + +fn operate(value: Value, head: Span) -> Value { + match value { + Value::Int { .. } => value, + Value::Float { val, span } => Value::Float { + val: val.ceil(), + span, + }, + other => Value::Error { + error: ShellError::UnsupportedInput( + String::from("Only numerical values are supported"), + other.span().unwrap_or(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/mod.rs b/crates/nu-command/src/math/mod.rs index 96466658db..2ff997c4e3 100644 --- a/crates/nu-command/src/math/mod.rs +++ b/crates/nu-command/src/math/mod.rs @@ -1,5 +1,6 @@ mod abs; mod avg; +mod ceil; pub mod command; mod floor; mod max; @@ -14,6 +15,7 @@ mod utils; pub use abs::SubCommand as MathAbs; pub use avg::SubCommand as MathAvg; +pub use ceil::SubCommand as MathCeil; pub use command::MathCommand as Math; pub use floor::SubCommand as MathFloor; pub use max::SubCommand as MathMax; diff --git a/crates/nu-command/src/math/mode.rs b/crates/nu-command/src/math/mode.rs index 126d6abc38..b3eb646b16 100644 --- a/crates/nu-command/src/math/mode.rs +++ b/crates/nu-command/src/math/mode.rs @@ -88,7 +88,7 @@ pub fn mode(values: &[Value], head: &Span) -> Result { // But f64 doesn't implement Hash, so we get the binary representation to use as // key in the HashMap let hashable_values: Result, ShellError> = values - .into_iter() + .iter() .map(|val| match val { Value::Int { val, .. } => Ok(HashableType::new(val.to_be_bytes(), NumberTypes::Int)), Value::Duration { val, .. } => {