diff --git a/crates/nu-cli/src/commands/math/avg.rs b/crates/nu-cli/src/commands/math/avg.rs index 23d2357d5..bb96490e1 100644 --- a/crates/nu-cli/src/commands/math/avg.rs +++ b/crates/nu-cli/src/commands/math/avg.rs @@ -1,4 +1,4 @@ -use crate::commands::math::utils::calculate; +use crate::commands::math::utils::run_with_function; use crate::commands::WholeStreamCommand; use crate::prelude::*; use crate::utils::data_processing::{reducer_for, Reduce}; @@ -30,7 +30,7 @@ impl WholeStreamCommand for SubCommand { args: CommandArgs, registry: &CommandRegistry, ) -> Result { - calculate( + run_with_function( RunnableContext { input: args.input, registry: registry.clone(), diff --git a/crates/nu-cli/src/commands/math/command.rs b/crates/nu-cli/src/commands/math/command.rs index 5e325523f..d9260f7b3 100644 --- a/crates/nu-cli/src/commands/math/command.rs +++ b/crates/nu-cli/src/commands/math/command.rs @@ -35,9 +35,10 @@ impl WholeStreamCommand for Command { mod tests { use super::*; use crate::commands::math::{ - avg::average, max::maximum, median::median, min::minimum, sum::summation, + avg::average, max::maximum, median::median, min::minimum, sum::summation, utils::calculate, utils::MathFunction, }; + use nu_plugin::row; use nu_plugin::test_helpers::value::{decimal, int}; use nu_protocol::Value; @@ -54,7 +55,7 @@ mod tests { description: &'static str, values: Vec, expected_err: Option, - // Order is: avg, min, max + // Order is: average, minimum, maximum, median, summation expected_res: Vec>, } let tt: Vec = vec![ @@ -124,17 +125,23 @@ mod tests { Ok(decimal(-15)), ], }, - // TODO-Uncomment once I figure out how to structure tables - // TestCase { - // description: "Tables", - // values: vec![ - // table(&vec![int(3), int(4), int(4)]), - // table(&vec![int(3), int(4), int(4)]), - // table(&vec![int(3), int(4), int(4)]), - // ], - // expected_err: None, - // expected_res: vec![Ok(decimal(-5)), Ok(decimal(-13.5)), Ok(int(10))], - // }, + TestCase { + description: "Tables Or Rows", + values: vec![ + row!["col1".to_owned() => int(1), "col2".to_owned() => int(5)], + row!["col1".to_owned() => int(2), "col2".to_owned() => int(6)], + row!["col1".to_owned() => int(3), "col2".to_owned() => int(7)], + row!["col1".to_owned() => int(4), "col2".to_owned() => int(8)], + ], + expected_err: None, + expected_res: vec![ + Ok(row!["col1".to_owned() => decimal(2.5), "col2".to_owned() => decimal(6.5)]), + Ok(row!["col1".to_owned() => int(1), "col2".to_owned() => int(5)]), + Ok(row!["col1".to_owned() => int(4), "col2".to_owned() => int(8)]), + Ok(row!["col1".to_owned() => decimal(2.5), "col2".to_owned() => decimal(6.5)]), + Ok(row!["col1".to_owned() => int(10), "col2".to_owned() => int(26)]), + ], + }, // TODO-Uncomment once Issue: https://github.com/nushell/nushell/issues/1883 is resolved // TestCase { // description: "Invalid Mixed Values", @@ -144,14 +151,14 @@ mod tests { // }, ]; let test_tag = Tag::unknown(); - for tc in tt.iter() { let tc: &TestCase = tc; // Just for type annotations let math_functions: Vec = vec![average, minimum, maximum, median, summation]; + let results = math_functions - .iter() - .map(|mf| mf(&tc.values, &test_tag)) + .into_iter() + .map(|mf| calculate(&tc.values, &test_tag, mf)) .collect_vec(); if tc.expected_err.is_some() { diff --git a/crates/nu-cli/src/commands/math/max.rs b/crates/nu-cli/src/commands/math/max.rs index 8d5354451..4c24399b3 100644 --- a/crates/nu-cli/src/commands/math/max.rs +++ b/crates/nu-cli/src/commands/math/max.rs @@ -1,4 +1,4 @@ -use crate::commands::math::utils::calculate; +use crate::commands::math::utils::run_with_function; use crate::commands::WholeStreamCommand; use crate::prelude::*; use crate::utils::data_processing::{reducer_for, Reduce}; @@ -26,7 +26,7 @@ impl WholeStreamCommand for SubCommand { args: CommandArgs, registry: &CommandRegistry, ) -> Result { - calculate( + run_with_function( RunnableContext { input: args.input, registry: registry.clone(), diff --git a/crates/nu-cli/src/commands/math/median.rs b/crates/nu-cli/src/commands/math/median.rs index 3748e0108..e376e97b5 100644 --- a/crates/nu-cli/src/commands/math/median.rs +++ b/crates/nu-cli/src/commands/math/median.rs @@ -1,4 +1,4 @@ -use crate::commands::math::utils::calculate; +use crate::commands::math::utils::run_with_function; use crate::commands::WholeStreamCommand; use crate::prelude::*; use crate::utils::data_processing::{reducer_for, Reduce}; @@ -30,7 +30,7 @@ impl WholeStreamCommand for SubCommand { args: CommandArgs, registry: &CommandRegistry, ) -> Result { - calculate( + run_with_function( RunnableContext { input: args.input, registry: registry.clone(), diff --git a/crates/nu-cli/src/commands/math/min.rs b/crates/nu-cli/src/commands/math/min.rs index 31e626827..2e13e05f2 100644 --- a/crates/nu-cli/src/commands/math/min.rs +++ b/crates/nu-cli/src/commands/math/min.rs @@ -1,4 +1,4 @@ -use crate::commands::math::utils::calculate; +use crate::commands::math::utils::run_with_function; use crate::commands::WholeStreamCommand; use crate::prelude::*; use crate::utils::data_processing::{reducer_for, Reduce}; @@ -26,7 +26,7 @@ impl WholeStreamCommand for SubCommand { args: CommandArgs, registry: &CommandRegistry, ) -> Result { - calculate( + run_with_function( RunnableContext { input: args.input, registry: registry.clone(), diff --git a/crates/nu-cli/src/commands/math/sum.rs b/crates/nu-cli/src/commands/math/sum.rs index 01fa5276c..c9475c233 100644 --- a/crates/nu-cli/src/commands/math/sum.rs +++ b/crates/nu-cli/src/commands/math/sum.rs @@ -1,4 +1,4 @@ -use crate::commands::math::utils::calculate; +use crate::commands::math::utils::run_with_function; use crate::commands::WholeStreamCommand; use crate::prelude::*; use crate::utils::data_processing::{reducer_for, Reduce}; @@ -27,7 +27,7 @@ impl WholeStreamCommand for SubCommand { args: CommandArgs, registry: &CommandRegistry, ) -> Result { - calculate( + run_with_function( RunnableContext { input: args.input, registry: registry.clone(), diff --git a/crates/nu-cli/src/commands/math/utils.rs b/crates/nu-cli/src/commands/math/utils.rs index 0102632b3..ecd90fa60 100644 --- a/crates/nu-cli/src/commands/math/utils.rs +++ b/crates/nu-cli/src/commands/math/utils.rs @@ -6,25 +6,29 @@ use indexmap::map::IndexMap; pub type MathFunction = fn(values: &[Value], tag: &Tag) -> Result; -pub async fn calculate( +pub async fn run_with_function( RunnableContext { mut input, name, .. }: RunnableContext, mf: MathFunction, ) -> Result { let values: Vec = input.drain_vec().await; + let res = calculate(&values, &name, mf); + match res { + Ok(v) => Ok(OutputStream::one(ReturnSuccess::value(v))), + Err(e) => Err(e), + } +} +pub fn calculate(values: &[Value], name: &Tag, mf: MathFunction) -> Result { if values.iter().all(|v| v.is_primitive()) { - match mf(&values, &name) { - Ok(result) => Ok(OutputStream::one(ReturnSuccess::value(result))), - Err(err) => Err(err), - } + mf(&values, &name) } else { // If we are not dealing with Primitives, then perhaps we are dealing with a table // Create a key for each column name let mut column_values = IndexMap::new(); for value in values { - if let UntaggedValue::Row(row_dict) = value.value { + if let UntaggedValue::Row(row_dict) = &value.value { for (key, value) in row_dict.entries.iter() { column_values .entry(key.clone()) @@ -44,11 +48,9 @@ pub async fn calculate( } } - Ok(OutputStream::one(ReturnSuccess::value( - UntaggedValue::Row(Dictionary { - entries: column_totals, - }) - .into_untagged_value(), - ))) + Ok(UntaggedValue::Row(Dictionary { + entries: column_totals, + }) + .into_untagged_value()) } }