forked from extern/nushell
Refactor out RunnableContext from calculate (#2037)
This commit is contained in:
parent
053bd926ec
commit
1420cbafe4
@ -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<OutputStream, ShellError> {
|
||||
calculate(
|
||||
run_with_function(
|
||||
RunnableContext {
|
||||
input: args.input,
|
||||
registry: registry.clone(),
|
||||
|
@ -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<Value>,
|
||||
expected_err: Option<ShellError>,
|
||||
// Order is: avg, min, max
|
||||
// Order is: average, minimum, maximum, median, summation
|
||||
expected_res: Vec<Result<Value, ShellError>>,
|
||||
}
|
||||
let tt: Vec<TestCase> = 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<MathFunction> =
|
||||
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() {
|
||||
|
@ -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<OutputStream, ShellError> {
|
||||
calculate(
|
||||
run_with_function(
|
||||
RunnableContext {
|
||||
input: args.input,
|
||||
registry: registry.clone(),
|
||||
|
@ -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<OutputStream, ShellError> {
|
||||
calculate(
|
||||
run_with_function(
|
||||
RunnableContext {
|
||||
input: args.input,
|
||||
registry: registry.clone(),
|
||||
|
@ -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<OutputStream, ShellError> {
|
||||
calculate(
|
||||
run_with_function(
|
||||
RunnableContext {
|
||||
input: args.input,
|
||||
registry: registry.clone(),
|
||||
|
@ -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<OutputStream, ShellError> {
|
||||
calculate(
|
||||
run_with_function(
|
||||
RunnableContext {
|
||||
input: args.input,
|
||||
registry: registry.clone(),
|
||||
|
@ -6,25 +6,29 @@ use indexmap::map::IndexMap;
|
||||
|
||||
pub type MathFunction = fn(values: &[Value], tag: &Tag) -> Result<Value, ShellError>;
|
||||
|
||||
pub async fn calculate(
|
||||
pub async fn run_with_function(
|
||||
RunnableContext {
|
||||
mut input, name, ..
|
||||
}: RunnableContext,
|
||||
mf: MathFunction,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let values: Vec<Value> = 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<Value, ShellError> {
|
||||
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())
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user