From 11d7d8ea1e83cc258141a9d97145de851238bdb6 Mon Sep 17 00:00:00 2001 From: Fernando Herrera Date: Sun, 12 Jun 2022 14:18:00 -0500 Subject: [PATCH] Remove dfr from dataframe commands (#5760) * input and output tests * input and output types for dfr * expression converter * remove deprecated command * correct expressions * cargo clippy * identifier for ls * cargo clippy * type for head and tail expression * modify full cell path if block --- crates/nu-cli/src/menus/help_completions.rs | 2 +- .../nu-command/src/dataframe/eager/append.rs | 20 +- .../nu-command/src/dataframe/eager/column.rs | 87 ---- .../nu-command/src/dataframe/eager/command.rs | 42 -- .../src/dataframe/eager/describe.rs | 14 +- crates/nu-command/src/dataframe/eager/drop.rs | 14 +- .../src/dataframe/eager/drop_duplicates.rs | 14 +- .../src/dataframe/eager/drop_nulls.rs | 22 +- .../nu-command/src/dataframe/eager/dtypes.rs | 14 +- .../nu-command/src/dataframe/eager/dummies.rs | 16 +- .../src/dataframe/eager/filter_with.rs | 27 +- .../nu-command/src/dataframe/eager/first.rs | 71 +-- crates/nu-command/src/dataframe/eager/get.rs | 16 +- crates/nu-command/src/dataframe/eager/last.rs | 69 +-- crates/nu-command/src/dataframe/eager/list.rs | 6 +- crates/nu-command/src/dataframe/eager/melt.rs | 16 +- crates/nu-command/src/dataframe/eager/mod.rs | 6 - crates/nu-command/src/dataframe/eager/open.rs | 14 +- .../nu-command/src/dataframe/eager/rename.rs | 27 +- .../nu-command/src/dataframe/eager/sample.rs | 16 +- .../nu-command/src/dataframe/eager/shape.rs | 14 +- .../nu-command/src/dataframe/eager/slice.rs | 14 +- crates/nu-command/src/dataframe/eager/take.rs | 24 +- .../nu-command/src/dataframe/eager/to_csv.rs | 16 +- .../nu-command/src/dataframe/eager/to_df.rs | 20 +- .../nu-command/src/dataframe/eager/to_nu.rs | 18 +- .../src/dataframe/eager/to_parquet.rs | 16 +- .../src/dataframe/eager/with_column.rs | 30 +- .../src/dataframe/expressions/alias.rs | 14 +- .../src/dataframe/expressions/as_nu.rs | 16 +- .../src/dataframe/expressions/col.rs | 16 +- .../expressions/expressions_macro.rs | 364 +++++++++++++- .../src/dataframe/expressions/lit.rs | 14 +- .../src/dataframe/expressions/mod.rs | 19 +- .../src/dataframe/expressions/otherwise.rs | 29 +- .../src/dataframe/expressions/quantile.rs | 102 ++++ .../src/dataframe/expressions/when.rs | 28 +- .../src/dataframe/lazy/aggregate.rs | 47 +- .../nu-command/src/dataframe/lazy/collect.rs | 14 +- crates/nu-command/src/dataframe/lazy/fetch.rs | 14 +- .../nu-command/src/dataframe/lazy/fill_na.rs | 12 +- .../src/dataframe/lazy/fill_null.rs | 14 +- .../nu-command/src/dataframe/lazy/groupby.rs | 47 +- crates/nu-command/src/dataframe/lazy/join.rs | 24 +- .../src/dataframe/lazy/macro_commands.rs | 461 +++++------------- crates/nu-command/src/dataframe/lazy/mod.rs | 4 +- .../nu-command/src/dataframe/lazy/quantile.rs | 96 ++-- .../nu-command/src/dataframe/lazy/select.rs | 14 +- .../src/dataframe/lazy/sort_by_expr.rs | 17 +- .../nu-command/src/dataframe/lazy/to_lazy.rs | 14 +- .../src/dataframe/series/all_false.rs | 18 +- .../src/dataframe/series/all_true.rs | 18 +- .../src/dataframe/series/arg_max.rs | 14 +- .../src/dataframe/series/arg_min.rs | 14 +- .../src/dataframe/series/cumulative.rs | 15 +- .../src/dataframe/series/date/as_date.rs | 14 +- .../src/dataframe/series/date/as_datetime.rs | 14 +- .../src/dataframe/series/date/get_day.rs | 16 +- .../src/dataframe/series/date/get_hour.rs | 16 +- .../src/dataframe/series/date/get_minute.rs | 16 +- .../src/dataframe/series/date/get_month.rs | 16 +- .../dataframe/series/date/get_nanosecond.rs | 16 +- .../src/dataframe/series/date/get_ordinal.rs | 16 +- .../src/dataframe/series/date/get_second.rs | 16 +- .../src/dataframe/series/date/get_week.rs | 16 +- .../src/dataframe/series/date/get_weekday.rs | 16 +- .../src/dataframe/series/date/get_year.rs | 16 +- .../src/dataframe/series/indexes/arg_sort.rs | 16 +- .../src/dataframe/series/indexes/arg_true.rs | 14 +- .../dataframe/series/indexes/arg_unique.rs | 14 +- .../dataframe/series/indexes/set_with_idx.rs | 18 +- .../dataframe/series/masks/is_duplicated.rs | 14 +- .../src/dataframe/series/masks/is_in.rs | 16 +- .../src/dataframe/series/masks/is_not_null.rs | 83 ++-- .../src/dataframe/series/masks/is_null.rs | 83 ++-- .../src/dataframe/series/masks/is_unique.rs | 14 +- .../src/dataframe/series/masks/not.rs | 79 ++- .../src/dataframe/series/masks/set.rs | 18 +- .../nu-command/src/dataframe/series/n_null.rs | 16 +- .../src/dataframe/series/n_unique.rs | 71 +-- .../src/dataframe/series/rolling.rs | 17 +- .../nu-command/src/dataframe/series/shift.rs | 23 +- .../dataframe/series/string/concatenate.rs | 16 +- .../src/dataframe/series/string/contains.rs | 14 +- .../src/dataframe/series/string/replace.rs | 14 +- .../dataframe/series/string/replace_all.rs | 14 +- .../dataframe/series/string/str_lengths.rs | 14 +- .../src/dataframe/series/string/str_slice.rs | 14 +- .../src/dataframe/series/string/strftime.rs | 16 +- .../dataframe/series/string/to_lowercase.rs | 14 +- .../dataframe/series/string/to_uppercase.rs | 14 +- .../nu-command/src/dataframe/series/unique.rs | 29 +- .../src/dataframe/series/value_counts.rs | 14 +- .../src/dataframe/test_dataframe.rs | 2 + .../src/dataframe/values/nu_expression/mod.rs | 436 +++++++++++++++-- crates/nu-command/src/default_context.rs | 3 - crates/nu-command/src/deprecated/dataframe.rs | 36 -- crates/nu-command/src/deprecated/mod.rs | 6 - crates/nu-parser/src/parse_keywords.rs | 109 +++-- crates/nu-parser/src/parser.rs | 55 ++- crates/nu-parser/src/type_check.rs | 66 ++- crates/nu-parser/tests/test_parser.rs | 253 +++++++++- crates/nu-protocol/src/engine/engine_state.rs | 53 +- crates/nu-protocol/src/engine/overlay.rs | 5 +- crates/nu-protocol/src/ty.rs | 2 +- 105 files changed, 2646 insertions(+), 1361 deletions(-) delete mode 100644 crates/nu-command/src/dataframe/eager/column.rs delete mode 100644 crates/nu-command/src/dataframe/eager/command.rs create mode 100644 crates/nu-command/src/dataframe/expressions/quantile.rs delete mode 100644 crates/nu-command/src/deprecated/dataframe.rs diff --git a/crates/nu-cli/src/menus/help_completions.rs b/crates/nu-cli/src/menus/help_completions.rs index 277daaa96..a2deecf65 100644 --- a/crates/nu-cli/src/menus/help_completions.rs +++ b/crates/nu-cli/src/menus/help_completions.rs @@ -87,7 +87,7 @@ impl NuHelpCompleter { let extra: Vec = examples .iter() - .map(|example| example.example.to_string()) + .map(|example| example.example.replace('\n', "\r\n")) .collect(); Suggestion { diff --git a/crates/nu-command/src/dataframe/eager/append.rs b/crates/nu-command/src/dataframe/eager/append.rs index a57ed9e99..4aab8a563 100644 --- a/crates/nu-command/src/dataframe/eager/append.rs +++ b/crates/nu-command/src/dataframe/eager/append.rs @@ -2,7 +2,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use super::super::values::{Axis, Column, NuDataFrame}; @@ -12,7 +12,7 @@ pub struct AppendDF; impl Command for AppendDF { fn name(&self) -> &str { - "dfr append" + "append" } fn usage(&self) -> &str { @@ -30,8 +30,8 @@ impl Command for AppendDF { vec![ Example { description: "Appends a dataframe as new columns", - example: r#"let a = ([[a b]; [1 2] [3 4]] | dfr to-df); - $a | dfr append $a"#, + example: r#"let a = ([[a b]; [1 2] [3 4]] | to-df); + $a | append $a"#, result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -57,8 +57,8 @@ impl Command for AppendDF { }, Example { description: "Appends a dataframe merging at the end of columns", - example: r#"let a = ([[a b]; [1 2] [3 4]] | dfr to-df); - $a | dfr append $a --col"#, + example: r#"let a = ([[a b]; [1 2] [3 4]] | to-df); + $a | append $a --col"#, result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -87,6 +87,14 @@ impl Command for AppendDF { ] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/eager/column.rs b/crates/nu-command/src/dataframe/eager/column.rs deleted file mode 100644 index 87f32daee..000000000 --- a/crates/nu-command/src/dataframe/eager/column.rs +++ /dev/null @@ -1,87 +0,0 @@ -use nu_engine::CallExt; -use nu_protocol::{ - ast::Call, - engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Value, -}; - -use super::super::values::{Column, NuDataFrame}; - -#[derive(Clone)] -pub struct ColumnDF; - -impl Command for ColumnDF { - fn name(&self) -> &str { - "dfr column" - } - - fn usage(&self) -> &str { - "Returns the selected column" - } - - fn signature(&self) -> Signature { - Signature::build(self.name()) - .required("column", SyntaxShape::String, "column name") - .category(Category::Custom("dataframe".into())) - } - - fn examples(&self) -> Vec { - vec![Example { - description: "Returns the selected column as series", - example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr column a", - result: Some( - NuDataFrame::try_from_columns(vec![Column::new( - "a".to_string(), - vec![Value::test_int(1), Value::test_int(3)], - )]) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }] - } - - fn run( - &self, - engine_state: &EngineState, - stack: &mut Stack, - call: &Call, - input: PipelineData, - ) -> Result { - command(engine_state, stack, call, input) - } -} - -fn command( - engine_state: &EngineState, - stack: &mut Stack, - call: &Call, - input: PipelineData, -) -> Result { - let column: Spanned = call.req(engine_state, stack, 0)?; - - let df = NuDataFrame::try_from_pipeline(input, call.head)?; - - let res = df.as_ref().column(&column.item).map_err(|e| { - ShellError::GenericError( - "Error selecting column".into(), - e.to_string(), - Some(column.span), - None, - Vec::new(), - ) - })?; - - NuDataFrame::try_from_series(vec![res.clone()], call.head) - .map(|df| PipelineData::Value(NuDataFrame::into_value(df, call.head), None)) -} - -#[cfg(test)] -mod test { - use super::super::super::test_dataframe::test_dataframe; - use super::*; - - #[test] - fn test_examples() { - test_dataframe(vec![Box::new(ColumnDF {})]) - } -} diff --git a/crates/nu-command/src/dataframe/eager/command.rs b/crates/nu-command/src/dataframe/eager/command.rs deleted file mode 100644 index f8ca63593..000000000 --- a/crates/nu-command/src/dataframe/eager/command.rs +++ /dev/null @@ -1,42 +0,0 @@ -use nu_engine::get_full_help; -use nu_protocol::{ - ast::Call, - engine::{Command, EngineState, Stack}, - Category, IntoPipelineData, PipelineData, ShellError, Signature, Value, -}; - -#[derive(Clone)] -pub struct Dataframe; - -impl Command for Dataframe { - fn name(&self) -> &str { - "dfr" - } - - fn usage(&self) -> &str { - "Dataframe commands" - } - - fn signature(&self) -> Signature { - Signature::build(self.name()).category(Category::Custom("dataframe".into())) - } - - fn run( - &self, - engine_state: &EngineState, - stack: &mut Stack, - call: &Call, - _input: PipelineData, - ) -> Result { - Ok(Value::String { - val: get_full_help( - &Dataframe.signature(), - &Dataframe.examples(), - engine_state, - stack, - ), - span: call.head, - } - .into_pipeline_data()) - } -} diff --git a/crates/nu-command/src/dataframe/eager/describe.rs b/crates/nu-command/src/dataframe/eager/describe.rs index b72807ddf..d5388eb69 100644 --- a/crates/nu-command/src/dataframe/eager/describe.rs +++ b/crates/nu-command/src/dataframe/eager/describe.rs @@ -4,7 +4,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use polars::{ chunked_array::ChunkedArray, @@ -19,7 +19,7 @@ pub struct DescribeDF; impl Command for DescribeDF { fn name(&self) -> &str { - "dfr describe" + "describe" } fn usage(&self) -> &str { @@ -40,7 +40,7 @@ impl Command for DescribeDF { fn examples(&self) -> Vec { vec![Example { description: "dataframe description", - example: "[[a b]; [1 1] [1 1]] | dfr to-df | dfr describe", + example: "[[a b]; [1 1] [1 1]] | to-df | describe", result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -95,6 +95,14 @@ impl Command for DescribeDF { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/eager/drop.rs b/crates/nu-command/src/dataframe/eager/drop.rs index 08eef0ac6..9d7d03212 100644 --- a/crates/nu-command/src/dataframe/eager/drop.rs +++ b/crates/nu-command/src/dataframe/eager/drop.rs @@ -2,7 +2,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use super::super::values::utils::convert_columns; @@ -13,7 +13,7 @@ pub struct DropDF; impl Command for DropDF { fn name(&self) -> &str { - "dfr drop" + "drop" } fn usage(&self) -> &str { @@ -29,7 +29,7 @@ impl Command for DropDF { fn examples(&self) -> Vec { vec![Example { description: "drop column a", - example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr drop a", + example: "[[a b]; [1 2] [3 4]] | to-df | drop a", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "b".to_string(), @@ -41,6 +41,14 @@ impl Command for DropDF { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/eager/drop_duplicates.rs b/crates/nu-command/src/dataframe/eager/drop_duplicates.rs index b6af6636d..04ae0b210 100644 --- a/crates/nu-command/src/dataframe/eager/drop_duplicates.rs +++ b/crates/nu-command/src/dataframe/eager/drop_duplicates.rs @@ -2,7 +2,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use polars::prelude::UniqueKeepStrategy; @@ -14,7 +14,7 @@ pub struct DropDuplicates; impl Command for DropDuplicates { fn name(&self) -> &str { - "dfr drop-duplicates" + "drop-duplicates" } fn usage(&self) -> &str { @@ -40,7 +40,7 @@ impl Command for DropDuplicates { fn examples(&self) -> Vec { vec![Example { description: "drop duplicates", - example: "[[a b]; [1 2] [3 4] [1 2]] | dfr to-df | dfr drop-duplicates", + example: "[[a b]; [1 2] [3 4] [1 2]] | to-df | drop-duplicates", result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -58,6 +58,14 @@ impl Command for DropDuplicates { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/eager/drop_nulls.rs b/crates/nu-command/src/dataframe/eager/drop_nulls.rs index eb6a42d55..cc7a5bcc2 100644 --- a/crates/nu-command/src/dataframe/eager/drop_nulls.rs +++ b/crates/nu-command/src/dataframe/eager/drop_nulls.rs @@ -2,7 +2,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use super::super::values::utils::convert_columns_string; @@ -13,7 +13,7 @@ pub struct DropNulls; impl Command for DropNulls { fn name(&self) -> &str { - "dfr drop-nulls" + "drop-nulls" } fn usage(&self) -> &str { @@ -34,10 +34,10 @@ impl Command for DropNulls { vec![ Example { description: "drop null values in dataframe", - example: r#"let df = ([[a b]; [1 2] [3 0] [1 2]] | dfr to-df); + example: r#"let df = ([[a b]; [1 2] [3 0] [1 2]] | to-df); let res = ($df.b / $df.b); - let a = ($df | dfr with-column $res --name res); - $a | dfr drop-nulls"#, + let a = ($df | with-column $res --name res); + $a | drop-nulls"#, result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -59,8 +59,8 @@ impl Command for DropNulls { }, Example { description: "drop null values in dataframe", - example: r#"let s = ([1 2 0 0 3 4] | dfr to-df); - ($s / $s) | dfr drop-nulls"#, + example: r#"let s = ([1 2 0 0 3 4] | to-df); + ($s / $s) | drop-nulls"#, result: Some( NuDataFrame::try_from_columns(vec![Column::new( "div_0_0".to_string(), @@ -78,6 +78,14 @@ impl Command for DropNulls { ] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/eager/dtypes.rs b/crates/nu-command/src/dataframe/eager/dtypes.rs index 923a032bc..0343cf3e3 100644 --- a/crates/nu-command/src/dataframe/eager/dtypes.rs +++ b/crates/nu-command/src/dataframe/eager/dtypes.rs @@ -2,7 +2,7 @@ use super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; #[derive(Clone)] @@ -10,7 +10,7 @@ pub struct DataTypes; impl Command for DataTypes { fn name(&self) -> &str { - "dfr dtypes" + "dtypes" } fn usage(&self) -> &str { @@ -24,7 +24,7 @@ impl Command for DataTypes { fn examples(&self) -> Vec { vec![Example { description: "Dataframe dtypes", - example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr dtypes", + example: "[[a b]; [1 2] [3 4]] | to-df | dtypes", result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -42,6 +42,14 @@ impl Command for DataTypes { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/eager/dummies.rs b/crates/nu-command/src/dataframe/eager/dummies.rs index fda678223..331e0633e 100644 --- a/crates/nu-command/src/dataframe/eager/dummies.rs +++ b/crates/nu-command/src/dataframe/eager/dummies.rs @@ -2,7 +2,7 @@ use super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use polars::prelude::DataFrameOps; @@ -11,7 +11,7 @@ pub struct Dummies; impl Command for Dummies { fn name(&self) -> &str { - "dfr to-dummies" + "to-dummies" } fn usage(&self) -> &str { @@ -26,7 +26,7 @@ impl Command for Dummies { vec![ Example { description: "Create new dataframe with dummy variables from a dataframe", - example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr to-dummies", + example: "[[a b]; [1 2] [3 4]] | to-df | to-dummies", result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -52,7 +52,7 @@ impl Command for Dummies { }, Example { description: "Create new dataframe with dummy variables from a series", - example: "[1 2 2 3 3] | dfr to-df | dfr to-dummies", + example: "[1 2 2 3 3] | to-df | to-dummies", result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -93,6 +93,14 @@ impl Command for Dummies { ] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/eager/filter_with.rs b/crates/nu-command/src/dataframe/eager/filter_with.rs index 910d09947..c5f288e09 100644 --- a/crates/nu-command/src/dataframe/eager/filter_with.rs +++ b/crates/nu-command/src/dataframe/eager/filter_with.rs @@ -2,7 +2,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use polars::prelude::LazyFrame; @@ -15,7 +15,7 @@ pub struct FilterWith; impl Command for FilterWith { fn name(&self) -> &str { - "dfr filter-with" + "filter-with" } fn usage(&self) -> &str { @@ -36,8 +36,8 @@ impl Command for FilterWith { vec![ Example { description: "Filter dataframe using a bool mask", - example: r#"let mask = ([true false] | dfr to-df); - [[a b]; [1 2] [3 4]] | dfr to-df | dfr filter-with $mask"#, + example: r#"let mask = ([true false] | to-df); + [[a b]; [1 2] [3 4]] | to-df | filter-with $mask"#, result: Some( NuDataFrame::try_from_columns(vec![ Column::new("a".to_string(), vec![Value::test_int(1)]), @@ -49,7 +49,7 @@ impl Command for FilterWith { }, Example { description: "Filter dataframe using an expression", - example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr filter-with ((dfr col a) > 1)", + example: "[[a b]; [1 2] [3 4]] | to-df | filter-with ((col a) > 1)", result: Some( NuDataFrame::try_from_columns(vec![ Column::new("a".to_string(), vec![Value::test_int(3)]), @@ -62,6 +62,14 @@ impl Command for FilterWith { ] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, @@ -74,16 +82,9 @@ impl Command for FilterWith { if NuLazyFrame::can_downcast(&value) { let df = NuLazyFrame::try_from_value(value)?; command_lazy(engine_state, stack, call, df) - } else if NuDataFrame::can_downcast(&value) { + } else { let df = NuDataFrame::try_from_value(value)?; command_eager(engine_state, stack, call, df) - } else { - Err(ShellError::CantConvert( - "expression or query".into(), - value.get_type().to_string(), - value.span()?, - None, - )) } } } diff --git a/crates/nu-command/src/dataframe/eager/first.rs b/crates/nu-command/src/dataframe/eager/first.rs index e09128ce2..0d4adc05c 100644 --- a/crates/nu-command/src/dataframe/eager/first.rs +++ b/crates/nu-command/src/dataframe/eager/first.rs @@ -1,10 +1,9 @@ use super::super::values::{utils::DEFAULT_ROWS, Column, NuDataFrame}; -use crate::dataframe::values::NuExpression; use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; #[derive(Clone)] @@ -12,39 +11,40 @@ pub struct FirstDF; impl Command for FirstDF { fn name(&self) -> &str { - "dfr first" + "first" } fn usage(&self) -> &str { - "Creates new dataframe with first rows or creates a first expression" + "Creates new dataframe with first rows" } fn signature(&self) -> Signature { Signature::build(self.name()) .optional("rows", SyntaxShape::Int, "Number of rows for head") - .category(Category::Custom("dataframe or expression".into())) + .category(Category::Custom("dataframe".into())) } fn examples(&self) -> Vec { - vec![ - Example { - description: "Create new dataframe with head rows", - example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr first 1", - result: Some( - NuDataFrame::try_from_columns(vec![ - Column::new("a".to_string(), vec![Value::test_int(1)]), - Column::new("b".to_string(), vec![Value::test_int(2)]), - ]) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }, - Example { - description: "Creates a first expression from a column", - example: "dfr col a | dfr first", - result: None, - }, - ] + vec![Example { + description: "Create new dataframe with head rows", + example: "[[a b]; [1 2] [3 4]] | to-df | first 1", + result: Some( + NuDataFrame::try_from_columns(vec![ + Column::new("a".to_string(), vec![Value::test_int(1)]), + Column::new("b".to_string(), vec![Value::test_int(2)]), + ]) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + }] + } + + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) } fn run( @@ -54,27 +54,8 @@ impl Command for FirstDF { call: &Call, input: PipelineData, ) -> Result { - let value = input.into_value(call.head); - - if NuExpression::can_downcast(&value) { - let expr = NuExpression::try_from_value(value)?; - let expr: NuExpression = expr.into_polars().is_null().into(); - - Ok(PipelineData::Value( - NuExpression::into_value(expr, call.head), - None, - )) - } else if NuDataFrame::can_downcast(&value) { - let df = NuDataFrame::try_from_value(value)?; - command(engine_state, stack, call, df) - } else { - Err(ShellError::CantConvert( - "expression or query".into(), - value.get_type().to_string(), - value.span()?, - None, - )) - } + let df = NuDataFrame::try_from_pipeline(input, call.head)?; + command(engine_state, stack, call, df) } } diff --git a/crates/nu-command/src/dataframe/eager/get.rs b/crates/nu-command/src/dataframe/eager/get.rs index 6d4a45d3c..c3fd97795 100644 --- a/crates/nu-command/src/dataframe/eager/get.rs +++ b/crates/nu-command/src/dataframe/eager/get.rs @@ -2,7 +2,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use crate::dataframe::values::utils::convert_columns_string; @@ -14,7 +14,7 @@ pub struct GetDF; impl Command for GetDF { fn name(&self) -> &str { - "dfr get" + "get" } fn usage(&self) -> &str { @@ -29,8 +29,8 @@ impl Command for GetDF { fn examples(&self) -> Vec { vec![Example { - description: "Creates dataframe with selected columns", - example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr get a", + description: "Returns the selected column", + example: "[[a b]; [1 2] [3 4]] | to-df | get a", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "a".to_string(), @@ -42,6 +42,14 @@ impl Command for GetDF { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/eager/last.rs b/crates/nu-command/src/dataframe/eager/last.rs index 1635cb22f..562d2956e 100644 --- a/crates/nu-command/src/dataframe/eager/last.rs +++ b/crates/nu-command/src/dataframe/eager/last.rs @@ -1,10 +1,9 @@ use super::super::values::{utils::DEFAULT_ROWS, Column, NuDataFrame}; -use crate::dataframe::values::NuExpression; use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; #[derive(Clone)] @@ -12,7 +11,7 @@ pub struct LastDF; impl Command for LastDF { fn name(&self) -> &str { - "dfr last" + "last" } fn usage(&self) -> &str { @@ -22,29 +21,30 @@ impl Command for LastDF { fn signature(&self) -> Signature { Signature::build(self.name()) .optional("rows", SyntaxShape::Int, "Number of rows for tail") - .category(Category::Custom("dataframe or lazyframe".into())) + .category(Category::Custom("dataframe".into())) } fn examples(&self) -> Vec { - vec![ - Example { - description: "Create new dataframe with last rows", - example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr last 1", - result: Some( - NuDataFrame::try_from_columns(vec![ - Column::new("a".to_string(), vec![Value::test_int(3)]), - Column::new("b".to_string(), vec![Value::test_int(4)]), - ]) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }, - Example { - description: "Creates a last expression from a column", - example: "dfr col a | dfr last", - result: None, - }, - ] + vec![Example { + description: "Create new dataframe with last rows", + example: "[[a b]; [1 2] [3 4]] | to-df | last 1", + result: Some( + NuDataFrame::try_from_columns(vec![ + Column::new("a".to_string(), vec![Value::test_int(3)]), + Column::new("b".to_string(), vec![Value::test_int(4)]), + ]) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + }] + } + + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) } fn run( @@ -54,27 +54,8 @@ impl Command for LastDF { call: &Call, input: PipelineData, ) -> Result { - let value = input.into_value(call.head); - - if NuExpression::can_downcast(&value) { - let expr = NuExpression::try_from_value(value)?; - let expr: NuExpression = expr.into_polars().is_null().into(); - - Ok(PipelineData::Value( - NuExpression::into_value(expr, call.head), - None, - )) - } else if NuDataFrame::can_downcast(&value) { - let df = NuDataFrame::try_from_value(value)?; - command(engine_state, stack, call, df) - } else { - Err(ShellError::CantConvert( - "expression or query".into(), - value.get_type().to_string(), - value.span()?, - None, - )) - } + let df = NuDataFrame::try_from_pipeline(input, call.head)?; + command(engine_state, stack, call, df) } } diff --git a/crates/nu-command/src/dataframe/eager/list.rs b/crates/nu-command/src/dataframe/eager/list.rs index 94dd5bea9..a12fa0e7d 100644 --- a/crates/nu-command/src/dataframe/eager/list.rs +++ b/crates/nu-command/src/dataframe/eager/list.rs @@ -11,7 +11,7 @@ pub struct ListDF; impl Command for ListDF { fn name(&self) -> &str { - "dfr ls" + "ls-df" } fn usage(&self) -> &str { @@ -25,8 +25,8 @@ impl Command for ListDF { fn examples(&self) -> Vec { vec![Example { description: "Creates a new dataframe and shows it in the dataframe list", - example: r#"let test = ([[a b];[1 2] [3 4]] | dfr to-df); - dfr ls"#, + example: r#"let test = ([[a b];[1 2] [3 4]] | to-df); + ls-df"#, result: None, }] } diff --git a/crates/nu-command/src/dataframe/eager/melt.rs b/crates/nu-command/src/dataframe/eager/melt.rs index 103a7cd19..082581b67 100644 --- a/crates/nu-command/src/dataframe/eager/melt.rs +++ b/crates/nu-command/src/dataframe/eager/melt.rs @@ -2,7 +2,8 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Type, + Value, }; use crate::dataframe::values::utils::convert_columns_string; @@ -14,7 +15,7 @@ pub struct MeltDF; impl Command for MeltDF { fn name(&self) -> &str { - "dfr melt" + "melt" } fn usage(&self) -> &str { @@ -53,8 +54,7 @@ impl Command for MeltDF { fn examples(&self) -> Vec { vec![Example { description: "melt dataframe", - example: - "[[a b c d]; [x 1 4 a] [y 2 5 b] [z 3 6 c]] | dfr to-df | dfr melt -c [b c] -v [a d]", + example: "[[a b c d]; [x 1 4 a] [y 2 5 b] [z 3 6 c]] | to-df | melt -c [b c] -v [a d]", result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -108,6 +108,14 @@ impl Command for MeltDF { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/eager/mod.rs b/crates/nu-command/src/dataframe/eager/mod.rs index 76bb832fd..da3c077f1 100644 --- a/crates/nu-command/src/dataframe/eager/mod.rs +++ b/crates/nu-command/src/dataframe/eager/mod.rs @@ -1,6 +1,4 @@ mod append; -mod column; -mod command; mod describe; mod drop; mod drop_duplicates; @@ -28,8 +26,6 @@ mod with_column; use nu_protocol::engine::StateWorkingSet; pub use append::AppendDF; -pub use column::ColumnDF; -pub use command::Dataframe; pub use describe::DescribeDF; pub use drop::DropDF; pub use drop_duplicates::DropDuplicates; @@ -67,8 +63,6 @@ pub fn add_eager_decls(working_set: &mut StateWorkingSet) { // Dataframe commands bind_command!( AppendDF, - ColumnDF, - Dataframe, DataTypes, DescribeDF, DropDF, diff --git a/crates/nu-command/src/dataframe/eager/open.rs b/crates/nu-command/src/dataframe/eager/open.rs index 08930487d..9239f7981 100644 --- a/crates/nu-command/src/dataframe/eager/open.rs +++ b/crates/nu-command/src/dataframe/eager/open.rs @@ -3,7 +3,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Spanned, SyntaxShape, + Category, Example, PipelineData, ShellError, Signature, Spanned, SyntaxShape, Type, }; use std::{fs::File, io::BufReader, path::PathBuf}; @@ -15,7 +15,7 @@ pub struct OpenDataFrame; impl Command for OpenDataFrame { fn name(&self) -> &str { - "dfr open" + "open-df" } fn usage(&self) -> &str { @@ -64,11 +64,19 @@ impl Command for OpenDataFrame { fn examples(&self) -> Vec { vec![Example { description: "Takes a file name and creates a dataframe", - example: "dfr open test.csv", + example: "open test.csv", result: None, }] } + fn input_type(&self) -> Type { + Type::Any + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/eager/rename.rs b/crates/nu-command/src/dataframe/eager/rename.rs index 5b3c18f8f..fb42e39ad 100644 --- a/crates/nu-command/src/dataframe/eager/rename.rs +++ b/crates/nu-command/src/dataframe/eager/rename.rs @@ -2,7 +2,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use crate::dataframe::{utils::extract_strings, values::NuLazyFrame}; @@ -14,7 +14,7 @@ pub struct RenameDF; impl Command for RenameDF { fn name(&self) -> &str { - "dfr rename" + "rename" } fn usage(&self) -> &str { @@ -40,7 +40,7 @@ impl Command for RenameDF { vec![ Example { description: "Renames a series", - example: "[5 6 7 8] | dfr to-df | dfr rename '0' new_name", + example: "[5 6 7 8] | to-df | rename '0' new_name", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "new_name".to_string(), @@ -57,7 +57,7 @@ impl Command for RenameDF { }, Example { description: "Renames a dataframe column", - example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr rename a a_new", + example: "[[a b]; [1 2] [3 4]] | to-df | rename a a_new", result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -75,7 +75,7 @@ impl Command for RenameDF { }, Example { description: "Renames two dataframe columns", - example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr rename [a b] [a_new b_new]", + example: "[[a b]; [1 2] [3 4]] | to-df | rename [a b] [a_new b_new]", result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -94,6 +94,14 @@ impl Command for RenameDF { ] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, @@ -106,16 +114,9 @@ impl Command for RenameDF { if NuLazyFrame::can_downcast(&value) { let df = NuLazyFrame::try_from_value(value)?; command_lazy(engine_state, stack, call, df) - } else if NuDataFrame::can_downcast(&value) { + } else { let df = NuDataFrame::try_from_value(value)?; command_eager(engine_state, stack, call, df) - } else { - Err(ShellError::CantConvert( - "expression or query".into(), - value.get_type().to_string(), - value.span()?, - None, - )) } } } diff --git a/crates/nu-command/src/dataframe/eager/sample.rs b/crates/nu-command/src/dataframe/eager/sample.rs index 45cb5dccc..73ec8f8bf 100644 --- a/crates/nu-command/src/dataframe/eager/sample.rs +++ b/crates/nu-command/src/dataframe/eager/sample.rs @@ -2,7 +2,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Spanned, SyntaxShape, + Category, Example, PipelineData, ShellError, Signature, Spanned, SyntaxShape, Type, }; use super::super::values::NuDataFrame; @@ -12,7 +12,7 @@ pub struct SampleDF; impl Command for SampleDF { fn name(&self) -> &str { - "dfr sample" + "sample" } fn usage(&self) -> &str { @@ -47,17 +47,25 @@ impl Command for SampleDF { vec![ Example { description: "Sample rows from dataframe", - example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr sample -n 1", + example: "[[a b]; [1 2] [3 4]] | to-df | sample -n 1", result: None, // No expected value because sampling is random }, Example { description: "Shows sample row using fraction and replace", - example: "[[a b]; [1 2] [3 4] [5 6]] | dfr to-df | dfr sample -f 0.5 -e", + example: "[[a b]; [1 2] [3 4] [5 6]] | to-df | sample -f 0.5 -e", result: None, // No expected value because sampling is random }, ] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/eager/shape.rs b/crates/nu-command/src/dataframe/eager/shape.rs index 32cda93a3..ca67e719c 100644 --- a/crates/nu-command/src/dataframe/eager/shape.rs +++ b/crates/nu-command/src/dataframe/eager/shape.rs @@ -1,7 +1,7 @@ use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use crate::dataframe::values::Column; @@ -13,7 +13,7 @@ pub struct ShapeDF; impl Command for ShapeDF { fn name(&self) -> &str { - "dfr shape" + "shape" } fn usage(&self) -> &str { @@ -27,7 +27,7 @@ impl Command for ShapeDF { fn examples(&self) -> Vec { vec![Example { description: "Shows row and column shape", - example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr shape", + example: "[[a b]; [1 2] [3 4]] | to-df | shape", result: Some( NuDataFrame::try_from_columns(vec![ Column::new("rows".to_string(), vec![Value::test_int(2)]), @@ -39,6 +39,14 @@ impl Command for ShapeDF { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/eager/slice.rs b/crates/nu-command/src/dataframe/eager/slice.rs index 087fe23aa..092e2ff9e 100644 --- a/crates/nu-command/src/dataframe/eager/slice.rs +++ b/crates/nu-command/src/dataframe/eager/slice.rs @@ -2,7 +2,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use crate::dataframe::values::Column; @@ -14,7 +14,7 @@ pub struct SliceDF; impl Command for SliceDF { fn name(&self) -> &str { - "dfr slice" + "slice" } fn usage(&self) -> &str { @@ -31,7 +31,7 @@ impl Command for SliceDF { fn examples(&self) -> Vec { vec![Example { description: "Create new dataframe from a slice of the rows", - example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr slice 0 1", + example: "[[a b]; [1 2] [3 4]] | to-df | slice 0 1", result: Some( NuDataFrame::try_from_columns(vec![ Column::new("a".to_string(), vec![Value::test_int(1)]), @@ -43,6 +43,14 @@ impl Command for SliceDF { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/eager/take.rs b/crates/nu-command/src/dataframe/eager/take.rs index c078de78a..cf7b1bf43 100644 --- a/crates/nu-command/src/dataframe/eager/take.rs +++ b/crates/nu-command/src/dataframe/eager/take.rs @@ -2,7 +2,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use polars::prelude::DataType; @@ -15,7 +15,7 @@ pub struct TakeDF; impl Command for TakeDF { fn name(&self) -> &str { - "dfr take" + "take" } fn usage(&self) -> &str { @@ -36,9 +36,9 @@ impl Command for TakeDF { vec![ Example { description: "Takes selected rows from dataframe", - example: r#"let df = ([[a b]; [4 1] [5 2] [4 3]] | dfr to-df); - let indices = ([0 2] | dfr to-df); - $df | dfr take $indices"#, + example: r#"let df = ([[a b]; [4 1] [5 2] [4 3]] | to-df); + let indices = ([0 2] | to-df); + $df | take $indices"#, result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -56,9 +56,9 @@ impl Command for TakeDF { }, Example { description: "Takes selected rows from series", - example: r#"let series = ([4 1 5 2 4 3] | dfr to-df); - let indices = ([0 2] | dfr to-df); - $series | dfr take $indices"#, + example: r#"let series = ([4 1 5 2 4 3] | to-df); + let indices = ([0 2] | to-df); + $series | take $indices"#, result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -71,6 +71,14 @@ impl Command for TakeDF { ] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/eager/to_csv.rs b/crates/nu-command/src/dataframe/eager/to_csv.rs index 480aa5365..bb4ffbf14 100644 --- a/crates/nu-command/src/dataframe/eager/to_csv.rs +++ b/crates/nu-command/src/dataframe/eager/to_csv.rs @@ -4,7 +4,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Spanned, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Spanned, SyntaxShape, Type, Value, }; use polars::prelude::{CsvWriter, SerWriter}; @@ -15,7 +15,7 @@ pub struct ToCSV; impl Command for ToCSV { fn name(&self) -> &str { - "dfr to-csv" + "to-csv" } fn usage(&self) -> &str { @@ -39,17 +39,25 @@ impl Command for ToCSV { vec![ Example { description: "Saves dataframe to csv file", - example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr to-csv test.csv", + example: "[[a b]; [1 2] [3 4]] | to-df | to-csv test.csv", result: None, }, Example { description: "Saves dataframe to csv file using other delimiter", - example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr to-csv test.csv -d '|'", + example: "[[a b]; [1 2] [3 4]] | to-df | to-csv test.csv -d '|'", result: None, }, ] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Any + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/eager/to_df.rs b/crates/nu-command/src/dataframe/eager/to_df.rs index c2558009e..7d90d3f39 100644 --- a/crates/nu-command/src/dataframe/eager/to_df.rs +++ b/crates/nu-command/src/dataframe/eager/to_df.rs @@ -3,7 +3,7 @@ use super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; #[derive(Clone)] @@ -11,7 +11,7 @@ pub struct ToDataFrame; impl Command for ToDataFrame { fn name(&self) -> &str { - "dfr to-df" + "to-df" } fn usage(&self) -> &str { @@ -26,7 +26,7 @@ impl Command for ToDataFrame { vec![ Example { description: "Takes a dictionary and creates a dataframe", - example: "[[a b];[1 2] [3 4]] | dfr to-df", + example: "[[a b];[1 2] [3 4]] | to-df", result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -44,7 +44,7 @@ impl Command for ToDataFrame { }, Example { description: "Takes a list of tables and creates a dataframe", - example: "[[1 2 a] [3 4 b] [5 6 c]] | dfr to-df", + example: "[[1 2 a] [3 4 b] [5 6 c]] | to-df", result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -70,7 +70,7 @@ impl Command for ToDataFrame { }, Example { description: "Takes a list and creates a dataframe", - example: "[a b c] | dfr to-df", + example: "[a b c] | to-df", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -86,7 +86,7 @@ impl Command for ToDataFrame { }, Example { description: "Takes a list of booleans and creates a dataframe", - example: "[true true false] | dfr to-df", + example: "[true true false] | to-df", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -103,6 +103,14 @@ impl Command for ToDataFrame { ] } + fn input_type(&self) -> Type { + Type::Any + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, _engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/eager/to_nu.rs b/crates/nu-command/src/dataframe/eager/to_nu.rs index cc60e2dfb..fec76c2ef 100644 --- a/crates/nu-command/src/dataframe/eager/to_nu.rs +++ b/crates/nu-command/src/dataframe/eager/to_nu.rs @@ -2,7 +2,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, SyntaxShape, Type, Value, }; use super::super::values::NuDataFrame; @@ -12,7 +12,7 @@ pub struct ToNu; impl Command for ToNu { fn name(&self) -> &str { - "dfr to-nu" + "to-nu" } fn usage(&self) -> &str { @@ -22,7 +22,7 @@ impl Command for ToNu { fn signature(&self) -> Signature { Signature::build(self.name()) .named( - "n-rows", + "rows", SyntaxShape::Number, "number of rows to be shown", Some('n'), @@ -35,17 +35,25 @@ impl Command for ToNu { vec![ Example { description: "Shows head rows from dataframe", - example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr to-nu", + example: "[[a b]; [1 2] [3 4]] | to-df | to nu", result: None, }, Example { description: "Shows tail rows from dataframe", - example: "[[a b]; [1 2] [3 4] [5 6]] | dfr to-df | dfr to-nu -t -n 1", + example: "[[a b]; [1 2] [3 4] [5 6]] | to-df | to nu -t -n 1", result: None, }, ] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Any + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/eager/to_parquet.rs b/crates/nu-command/src/dataframe/eager/to_parquet.rs index 6cce4ebaf..f08754d83 100644 --- a/crates/nu-command/src/dataframe/eager/to_parquet.rs +++ b/crates/nu-command/src/dataframe/eager/to_parquet.rs @@ -4,7 +4,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Spanned, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Spanned, SyntaxShape, Type, Value, }; use polars::prelude::ParquetWriter; @@ -15,7 +15,7 @@ pub struct ToParquet; impl Command for ToParquet { fn name(&self) -> &str { - "dfr to-parquet" + "to-parquet" } fn usage(&self) -> &str { @@ -30,12 +30,20 @@ impl Command for ToParquet { fn examples(&self) -> Vec { vec![Example { - description: "Saves dataframe to csv file", - example: "[[a b]; [1 2] [3 4]] | dfr to-df | dfr to-parquet test.parquet", + description: "Saves dataframe to parquet file", + example: "[[a b]; [1 2] [3 4]] | to-df | to-parquet test.parquet", result: None, }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Any + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/eager/with_column.rs b/crates/nu-command/src/dataframe/eager/with_column.rs index 8f5314f0d..b5eea24bf 100644 --- a/crates/nu-command/src/dataframe/eager/with_column.rs +++ b/crates/nu-command/src/dataframe/eager/with_column.rs @@ -4,7 +4,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; #[derive(Clone)] @@ -12,7 +12,7 @@ pub struct WithColumn; impl Command for WithColumn { fn name(&self) -> &str { - "dfr with-column" + "with-column" } fn usage(&self) -> &str { @@ -34,9 +34,9 @@ impl Command for WithColumn { vec![ Example { description: "Adds a series to the dataframe", - example: r#"[[a b]; [1 2] [3 4]] - | dfr to-df - | dfr with-column ([5 6] | dfr to-df) --name c"#, + example: r#"[[a b]; [1 2] [3 4]] + | to-df + | with-column ([5 6] | to-df) --name c"#, result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -58,13 +58,13 @@ impl Command for WithColumn { }, Example { description: "Adds a series to the dataframe", - example: r#"[[a b]; [1 2] [3 4]] - | dfr to-lazy - | dfr with-column [ - ((dfr col a) * 2 | dfr as "c") - ((dfr col a) * 3 | dfr as "d") + example: r#"[[a b]; [1 2] [3 4]] + | to-lazy + | with-column [ + ((col a) * 2 | as "c") + ((col a) * 3 | as "d") ] - | dfr collect"#, + | collect"#, result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -91,6 +91,14 @@ impl Command for WithColumn { ] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/expressions/alias.rs b/crates/nu-command/src/dataframe/expressions/alias.rs index 0fe590b20..00e0e8b2b 100644 --- a/crates/nu-command/src/dataframe/expressions/alias.rs +++ b/crates/nu-command/src/dataframe/expressions/alias.rs @@ -4,7 +4,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; #[derive(Clone)] @@ -12,7 +12,7 @@ pub struct ExprAlias; impl Command for ExprAlias { fn name(&self) -> &str { - "dfr as" + "as" } fn usage(&self) -> &str { @@ -32,7 +32,7 @@ impl Command for ExprAlias { fn examples(&self) -> Vec { vec![Example { description: "Creates and alias expression", - example: "dfr col a | dfr as new_a | dfr as-nu", + example: "col a | as new_a | to-nu", result: { let cols = vec!["expr".into(), "value".into()]; let expr = Value::test_string("column"); @@ -57,6 +57,14 @@ impl Command for ExprAlias { }] } + fn input_type(&self) -> Type { + Type::Custom("expression".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("expression".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/expressions/as_nu.rs b/crates/nu-command/src/dataframe/expressions/as_nu.rs index 54fd9f498..8c7749df0 100644 --- a/crates/nu-command/src/dataframe/expressions/as_nu.rs +++ b/crates/nu-command/src/dataframe/expressions/as_nu.rs @@ -3,7 +3,7 @@ use super::super::values::NuExpression; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; #[derive(Clone)] @@ -11,7 +11,7 @@ pub struct ExprAsNu; impl Command for ExprAsNu { fn name(&self) -> &str { - "dfr as-nu" + "to-nu" } fn usage(&self) -> &str { @@ -25,7 +25,7 @@ impl Command for ExprAsNu { fn examples(&self) -> Vec { vec![Example { description: "Convert a col expression into a nushell value", - example: "dfr col col_a | dfr as-nu", + example: "col a | to-nu", result: Some(Value::Record { cols: vec!["expr".into(), "value".into()], vals: vec![ @@ -34,7 +34,7 @@ impl Command for ExprAsNu { span: Span::test_data(), }, Value::String { - val: "col_a".into(), + val: "a".into(), span: Span::test_data(), }, ], @@ -43,6 +43,14 @@ impl Command for ExprAsNu { }] } + fn input_type(&self) -> Type { + Type::Custom("expression".into()) + } + + fn output_type(&self) -> Type { + Type::Any + } + fn run( &self, _engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/expressions/col.rs b/crates/nu-command/src/dataframe/expressions/col.rs index 4bd783e35..2936c0acb 100644 --- a/crates/nu-command/src/dataframe/expressions/col.rs +++ b/crates/nu-command/src/dataframe/expressions/col.rs @@ -3,7 +3,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use polars::prelude::col; @@ -12,7 +12,7 @@ pub struct ExprCol; impl Command for ExprCol { fn name(&self) -> &str { - "dfr col" + "col" } fn usage(&self) -> &str { @@ -32,7 +32,7 @@ impl Command for ExprCol { fn examples(&self) -> Vec { vec![Example { description: "Creates a named column expression and converts it to a nu object", - example: "dfr col col_a | dfr as-nu", + example: "col a | to-nu", result: Some(Value::Record { cols: vec!["expr".into(), "value".into()], vals: vec![ @@ -41,7 +41,7 @@ impl Command for ExprCol { span: Span::test_data(), }, Value::String { - val: "col_a".into(), + val: "a".into(), span: Span::test_data(), }, ], @@ -50,6 +50,14 @@ impl Command for ExprCol { }] } + fn input_type(&self) -> Type { + Type::Any + } + + fn output_type(&self) -> Type { + Type::Custom("expression".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/expressions/expressions_macro.rs b/crates/nu-command/src/dataframe/expressions/expressions_macro.rs index 17149eec5..c473317fe 100644 --- a/crates/nu-command/src/dataframe/expressions/expressions_macro.rs +++ b/crates/nu-command/src/dataframe/expressions/expressions_macro.rs @@ -1,18 +1,17 @@ /// Definition of multiple Expression commands using a macro rule /// All of these expressions have an identical body and only require /// to have a change in the name, description and expression function -use super::super::values::NuExpression; - +use crate::dataframe::values::{Column, NuDataFrame, NuExpression}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; // The structs defined in this file are structs that form part of other commands // since they share a similar name macro_rules! expr_command { - ($command: ident, $name: expr, $desc: expr, $examples: expr, $func: ident) => { + ($command: ident, $name: expr, $desc: expr, $examples: expr, $func: ident, $test: ident) => { #[derive(Clone)] pub struct $command; @@ -33,6 +32,14 @@ macro_rules! expr_command { $examples } + fn input_type(&self) -> Type { + Type::Custom("expression".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("expression".into()) + } + fn run( &self, _engine_state: &EngineState, @@ -49,6 +56,23 @@ macro_rules! expr_command { )) } } + + #[cfg(test)] + mod $test { + use super::super::super::test_dataframe::test_dataframe; + use super::*; + use crate::dataframe::lazy::aggregate::LazyAggregate; + use crate::dataframe::lazy::groupby::ToLazyGroupBy; + + #[test] + fn test_examples() { + test_dataframe(vec![ + Box::new($command {}), + Box::new(LazyAggregate {}), + Box::new(ToLazyGroupBy {}), + ]) + } + } }; } @@ -56,68 +80,380 @@ macro_rules! expr_command { // Expands to a command definition for a list expression expr_command!( ExprList, - "dfr list", + "list", "Aggregates a group to a Series", vec![Example { description: "", example: "", result: None, }], - list + list, + test_list ); // ExprAggGroups command // Expands to a command definition for a agg groups expression expr_command!( ExprAggGroups, - "dfr agg-groups", + "agg-groups", "creates an agg_groups expression", vec![Example { description: "", example: "", result: None, }], - agg_groups + agg_groups, + test_groups ); // ExprFlatten command // Expands to a command definition for a flatten expression expr_command!( ExprFlatten, - "dfr flatten", + "flatten", "creates a flatten expression", vec![Example { description: "", example: "", result: None, }], - flatten + flatten, + test_flatten ); // ExprExplode command // Expands to a command definition for a explode expression expr_command!( ExprExplode, - "dfr explode", + "explode", "creates an explode expression", vec![Example { description: "", example: "", result: None, }], - explode + explode, + test_explode ); // ExprCount command // Expands to a command definition for a count expression expr_command!( ExprCount, - "dfr count", + "count", "creates a count expression", vec![Example { description: "", example: "", result: None, }], - count + count, + test_count +); + +// ExprFirst command +// Expands to a command definition for a count expression +expr_command!( + ExprFirst, + "first", + "creates a first expression", + vec![Example { + description: "Creates a first expression from a column", + example: "col a | first", + result: None, + },], + first, + test_first +); + +// ExprLast command +// Expands to a command definition for a count expression +expr_command!( + ExprLast, + "last", + "creates a last expression", + vec![Example { + description: "Creates a last expression from a column", + example: "col a | last", + result: None, + },], + last, + test_last +); + +// ExprNUnique command +// Expands to a command definition for a n-unique expression +expr_command!( + ExprNUnique, + "n-unique", + "creates a n-unique expression", + vec![Example { + description: "Creates a is n-unique expression from a column", + example: "col a | n-unique", + result: None, + },], + n_unique, + test_nunique +); + +// ExprIsNotNull command +// Expands to a command definition for a n-unique expression +expr_command!( + ExprIsNotNull, + "is-not-null", + "creates a is not null expression", + vec![Example { + description: "Creates a is not null expression from a column", + example: "col a | is-not-null", + result: None, + },], + is_not_null, + test_is_not_null +); + +// ExprIsNull command +// Expands to a command definition for a n-unique expression +expr_command!( + ExprIsNull, + "is-null", + "creates a is null expression", + vec![Example { + description: "Creates a is null expression from a column", + example: "col a | is-null", + result: None, + },], + is_null, + test_is_null +); + +// ExprNot command +// Expands to a command definition for a not expression +expr_command!( + ExprNot, + "expr-not", + "creates a not expression", + vec![Example { + description: "Creates a not expression", + example: "(col a) > 2) | expr-not", + result: None, + },], + not, + test_not +); + +// ExprMax command +// Expands to a command definition for max aggregation +expr_command!( + ExprMax, + "max", + "Creates a max expression", + vec![Example { + description: "Max aggregation for a group by", + example: r#"[[a b]; [one 2] [one 4] [two 1]] + | to-df + | group-by a + | agg (col b | max)"#, + result: Some( + NuDataFrame::try_from_columns(vec![ + Column::new( + "a".to_string(), + vec![Value::test_string("one"), Value::test_string("two")], + ), + Column::new( + "b".to_string(), + vec![Value::test_int(4), Value::test_int(1)], + ), + ]) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + },], + max, + test_max +); + +// ExprMin command +// Expands to a command definition for min aggregation +expr_command!( + ExprMin, + "min", + "Creates a min expression", + vec![Example { + description: "Min aggregation for a group by", + example: r#"[[a b]; [one 2] [one 4] [two 1]] + | to-df + | group-by a + | agg (col b | min)"#, + result: Some( + NuDataFrame::try_from_columns(vec![ + Column::new( + "a".to_string(), + vec![Value::test_string("one"), Value::test_string("two")], + ), + Column::new( + "b".to_string(), + vec![Value::test_int(2), Value::test_int(1)], + ), + ]) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + },], + min, + test_min +); + +// ExprSum command +// Expands to a command definition for sum aggregation +expr_command!( + ExprSum, + "sum", + "Creates a sum expression for an aggregation", + vec![Example { + description: "Sum aggregation for a group by", + example: r#"[[a b]; [one 2] [one 4] [two 1]] + | to-df + | group-by a + | agg (col b | sum)"#, + result: Some( + NuDataFrame::try_from_columns(vec![ + Column::new( + "a".to_string(), + vec![Value::test_string("one"), Value::test_string("two")], + ), + Column::new( + "b".to_string(), + vec![Value::test_int(6), Value::test_int(1)], + ), + ]) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + },], + sum, + test_sum +); + +// ExprMean command +// Expands to a command definition for mean aggregation +expr_command!( + ExprMean, + "mean", + "Creates a mean expression for an aggregation", + vec![Example { + description: "Mean aggregation for a group by", + example: r#"[[a b]; [one 2] [one 4] [two 1]] + | to-df + | group-by a + | agg (col b | mean)"#, + result: Some( + NuDataFrame::try_from_columns(vec![ + Column::new( + "a".to_string(), + vec![Value::test_string("one"), Value::test_string("two")], + ), + Column::new( + "b".to_string(), + vec![Value::test_float(3.0), Value::test_float(1.0)], + ), + ]) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + },], + mean, + test_mean +); + +// ExprMedian command +// Expands to a command definition for median aggregation +expr_command!( + ExprMedian, + "median", + "Creates a median expression for an aggregation", + vec![Example { + description: "Median aggregation for a group by", + example: r#"[[a b]; [one 2] [one 4] [two 1]] + | to-df + | group-by a + | agg (col b | median)"#, + result: Some( + NuDataFrame::try_from_columns(vec![ + Column::new( + "a".to_string(), + vec![Value::test_string("one"), Value::test_string("two")], + ), + Column::new( + "b".to_string(), + vec![Value::test_float(3.0), Value::test_float(1.0)], + ), + ]) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + },], + median, + test_median +); + +// ExprStd command +// Expands to a command definition for std aggregation +expr_command!( + ExprStd, + "std", + "Creates a std expression for an aggregation", + vec![Example { + description: "Std aggregation for a group by", + example: r#"[[a b]; [one 2] [one 2] [two 1] [two 1]] + | to-df + | group-by a + | agg (col b | std)"#, + result: Some( + NuDataFrame::try_from_columns(vec![ + Column::new( + "a".to_string(), + vec![Value::test_string("one"), Value::test_string("two")], + ), + Column::new( + "b".to_string(), + vec![Value::test_float(0.0), Value::test_float(0.0)], + ), + ]) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + },], + std, + test_std +); + +// ExprVar command +// Expands to a command definition for var aggregation +expr_command!( + ExprVar, + "var", + "Create a var expression for an aggregation", + vec![Example { + description: "Var aggregation for a group by", + example: r#"[[a b]; [one 2] [one 2] [two 1] [two 1]] + | to-df + | group-by a + | agg (col b | var)"#, + result: Some( + NuDataFrame::try_from_columns(vec![ + Column::new( + "a".to_string(), + vec![Value::test_string("one"), Value::test_string("two")], + ), + Column::new( + "b".to_string(), + vec![Value::test_float(0.0), Value::test_float(0.0)], + ), + ]) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + },], + var, + test_var ); diff --git a/crates/nu-command/src/dataframe/expressions/lit.rs b/crates/nu-command/src/dataframe/expressions/lit.rs index 3fe9647ab..e80e0c90a 100644 --- a/crates/nu-command/src/dataframe/expressions/lit.rs +++ b/crates/nu-command/src/dataframe/expressions/lit.rs @@ -3,7 +3,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; #[derive(Clone)] @@ -11,7 +11,7 @@ pub struct ExprLit; impl Command for ExprLit { fn name(&self) -> &str { - "dfr lit" + "lit" } fn usage(&self) -> &str { @@ -31,7 +31,7 @@ impl Command for ExprLit { fn examples(&self) -> Vec { vec![Example { description: "Created a literal expression and converts it to a nu object", - example: "dfr lit 2 | dfr as-nu", + example: "lit 2 | to-nu", result: Some(Value::Record { cols: vec!["expr".into(), "value".into()], vals: vec![ @@ -49,6 +49,14 @@ impl Command for ExprLit { }] } + fn input_type(&self) -> Type { + Type::Any + } + + fn output_type(&self) -> Type { + Type::Custom("expression".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/expressions/mod.rs b/crates/nu-command/src/dataframe/expressions/mod.rs index 63d2f5854..74b8714d3 100644 --- a/crates/nu-command/src/dataframe/expressions/mod.rs +++ b/crates/nu-command/src/dataframe/expressions/mod.rs @@ -4,6 +4,7 @@ mod col; mod expressions_macro; mod lit; mod otherwise; +mod quantile; mod when; use nu_protocol::engine::StateWorkingSet; @@ -14,6 +15,7 @@ pub(super) use crate::dataframe::expressions::col::ExprCol; pub(crate) use crate::dataframe::expressions::expressions_macro::*; pub(super) use crate::dataframe::expressions::lit::ExprLit; pub(super) use crate::dataframe::expressions::otherwise::ExprOtherwise; +pub(super) use crate::dataframe::expressions::quantile::ExprQuantile; pub(super) use crate::dataframe::expressions::when::ExprWhen; pub fn add_expressions(working_set: &mut StateWorkingSet) { @@ -35,9 +37,24 @@ pub fn add_expressions(working_set: &mut StateWorkingSet) { ExprAsNu, ExprWhen, ExprOtherwise, + ExprQuantile, ExprList, ExprAggGroups, ExprFlatten, - ExprExplode + ExprExplode, + ExprCount, + ExprFirst, + ExprLast, + ExprNUnique, + ExprIsNotNull, + ExprIsNull, + ExprNot, + ExprMax, + ExprMin, + ExprSum, + ExprMean, + ExprMedian, + ExprStd, + ExprVar ); } diff --git a/crates/nu-command/src/dataframe/expressions/otherwise.rs b/crates/nu-command/src/dataframe/expressions/otherwise.rs index df3f2210a..cc3294138 100644 --- a/crates/nu-command/src/dataframe/expressions/otherwise.rs +++ b/crates/nu-command/src/dataframe/expressions/otherwise.rs @@ -3,7 +3,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; #[derive(Clone)] @@ -11,7 +11,7 @@ pub struct ExprOtherwise; impl Command for ExprOtherwise { fn name(&self) -> &str { - "dfr otherwise" + "otherwise" } fn usage(&self) -> &str { @@ -32,26 +32,25 @@ impl Command for ExprOtherwise { vec![ Example { description: "Create a when conditions", - example: "dfr when ((dfr col a) > 2) 4 | dfr otherwise 5", + example: "when ((col a) > 2) 4 | otherwise 5", result: None, }, Example { description: "Create a when conditions", - example: - "dfr when ((dfr col a) > 2) 4 | dfr when ((dfr col a) < 0) 6 | dfr otherwise 0", + example: "when ((col a) > 2) 4 | when ((col a) < 0) 6 | otherwise 0", result: None, }, Example { description: "Create a new column for the dataframe", example: r#"[[a b]; [6 2] [1 4] [4 1]] - | dfr to-lazy - | dfr with-column ( - dfr when ((dfr col a) > 2) 4 | dfr otherwise 5 | dfr as c + | to-lazy + | with-column ( + when ((col a) > 2) 4 | otherwise 5 | as c ) - | dfr with-column ( - dfr when ((dfr col a) > 5) 10 | dfr when ((dfr col a) < 2) 6 | dfr otherwise 0 | dfr as d + | with-column ( + when ((col a) > 5) 10 | when ((col a) < 2) 6 | otherwise 0 | as d ) - | dfr collect"#, + | collect"#, result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -78,6 +77,14 @@ impl Command for ExprOtherwise { ] } + fn input_type(&self) -> Type { + Type::Any + } + + fn output_type(&self) -> Type { + Type::Custom("expression".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/expressions/quantile.rs b/crates/nu-command/src/dataframe/expressions/quantile.rs new file mode 100644 index 000000000..d7287ef4f --- /dev/null +++ b/crates/nu-command/src/dataframe/expressions/quantile.rs @@ -0,0 +1,102 @@ +use crate::dataframe::values::{Column, NuDataFrame, NuExpression}; +use nu_engine::CallExt; +use nu_protocol::{ + ast::Call, + engine::{Command, EngineState, Stack}, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, +}; +use polars::prelude::QuantileInterpolOptions; + +#[derive(Clone)] +pub struct ExprQuantile; + +impl Command for ExprQuantile { + fn name(&self) -> &str { + "quantile" + } + + fn usage(&self) -> &str { + "Aggregates the columns to the selected quantile" + } + + fn signature(&self) -> Signature { + Signature::build(self.name()) + .required( + "quantile", + SyntaxShape::Number, + "quantile value for quantile operation", + ) + .category(Category::Custom("expression".into())) + } + + fn examples(&self) -> Vec { + vec![Example { + description: "Quantile aggregation for a group by", + example: r#"[[a b]; [one 2] [one 4] [two 1]] + | to-df + | group-by a + | agg (col b | quantile 0.5)"#, + result: Some( + NuDataFrame::try_from_columns(vec![ + Column::new( + "a".to_string(), + vec![Value::test_string("one"), Value::test_string("two")], + ), + Column::new( + "b".to_string(), + vec![Value::test_float(4.0), Value::test_float(1.0)], + ), + ]) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + }] + } + + fn input_type(&self) -> Type { + Type::Custom("expression".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("expression".into()) + } + + fn run( + &self, + engine_state: &EngineState, + stack: &mut Stack, + call: &Call, + input: PipelineData, + ) -> Result { + let value = input.into_value(call.head); + let quantile: f64 = call.req(engine_state, stack, 0)?; + + let expr = NuExpression::try_from_value(value)?; + let expr: NuExpression = expr + .into_polars() + .quantile(quantile, QuantileInterpolOptions::default()) + .into(); + + Ok(PipelineData::Value( + NuExpression::into_value(expr, call.head), + None, + )) + } +} + +#[cfg(test)] +mod test { + use super::super::super::test_dataframe::test_dataframe; + use super::*; + use crate::dataframe::lazy::aggregate::LazyAggregate; + use crate::dataframe::lazy::groupby::ToLazyGroupBy; + + #[test] + fn test_examples() { + test_dataframe(vec![ + Box::new(ExprQuantile {}), + Box::new(LazyAggregate {}), + Box::new(ToLazyGroupBy {}), + ]) + } +} diff --git a/crates/nu-command/src/dataframe/expressions/when.rs b/crates/nu-command/src/dataframe/expressions/when.rs index 722d3d369..ccafc9618 100644 --- a/crates/nu-command/src/dataframe/expressions/when.rs +++ b/crates/nu-command/src/dataframe/expressions/when.rs @@ -3,7 +3,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use polars::prelude::when; @@ -12,7 +12,7 @@ pub struct ExprWhen; impl Command for ExprWhen { fn name(&self) -> &str { - "dfr when" + "when" } fn usage(&self) -> &str { @@ -38,25 +38,25 @@ impl Command for ExprWhen { vec![ Example { description: "Create a when conditions", - example: "dfr when ((dfr col a) > 2) 4", + example: "when ((col a) > 2) 4", result: None, }, Example { description: "Create a when conditions", - example: "dfr when ((dfr col a) > 2) 4 | dfr when ((dfr col a) < 0) 6", + example: "when ((col a) > 2) 4 | when ((col a) < 0) 6", result: None, }, Example { description: "Create a new column for the dataframe", example: r#"[[a b]; [6 2] [1 4] [4 1]] - | dfr to-lazy - | dfr with-column ( - dfr when ((dfr col a) > 2) 4 | dfr otherwise 5 | dfr as c + | to-lazy + | with-column ( + when ((col a) > 2) 4 | otherwise 5 | as c ) - | dfr with-column ( - dfr when ((dfr col a) > 5) 10 | dfr when ((dfr col a) < 2) 6 | dfr otherwise 0 | dfr as d + | with-column ( + when ((col a) > 5) 10 | when ((col a) < 2) 6 | otherwise 0 | as d ) - | dfr collect"#, + | collect"#, result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -83,6 +83,14 @@ impl Command for ExprWhen { ] } + fn input_type(&self) -> Type { + Type::Custom("expression".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("expression".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/lazy/aggregate.rs b/crates/nu-command/src/dataframe/lazy/aggregate.rs index 957eb750e..752585f52 100644 --- a/crates/nu-command/src/dataframe/lazy/aggregate.rs +++ b/crates/nu-command/src/dataframe/lazy/aggregate.rs @@ -4,7 +4,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; #[derive(Clone)] @@ -12,7 +12,7 @@ pub struct LazyAggregate; impl Command for LazyAggregate { fn name(&self) -> &str { - "dfr agg" + "agg" } fn usage(&self) -> &str { @@ -34,12 +34,12 @@ impl Command for LazyAggregate { Example { description: "Group by and perform an aggregation", example: r#"[[a b]; [1 2] [1 4] [2 6] [2 4]] - | dfr to-df - | dfr group-by a - | dfr agg [ - ("b" | dfr min | dfr as "b_min") - ("b" | dfr max | dfr as "b_max") - ("b" | dfr sum | dfr as "b_sum") + | to-df + | group-by a + | agg [ + (col b | min | as "b_min") + (col b | max | as "b_max") + (col b | sum | as "b_sum") ]"#, result: Some( NuDataFrame::try_from_columns(vec![ @@ -67,14 +67,14 @@ impl Command for LazyAggregate { Example { description: "Group by and perform an aggregation", example: r#"[[a b]; [1 2] [1 4] [2 6] [2 4]] - | dfr to-lazy - | dfr group-by a - | dfr agg [ - ("b" | dfr min | dfr as "b_min") - ("b" | dfr max | dfr as "b_max") - ("b" | dfr sum | dfr as "b_sum") + | to-lazy + | group-by a + | agg [ + (col b | min | as "b_min") + (col b | max | as "b_max") + (col b | sum | as "b_sum") ] - | dfr collect"#, + | collect"#, result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -101,6 +101,14 @@ impl Command for LazyAggregate { ] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, @@ -133,9 +141,8 @@ impl Command for LazyAggregate { mod test { use super::super::super::test_dataframe::test_dataframe; use super::*; - use crate::dataframe::expressions::ExprAlias; + use crate::dataframe::expressions::{ExprAlias, ExprMax, ExprMin, ExprSum}; use crate::dataframe::lazy::groupby::ToLazyGroupBy; - use crate::dataframe::lazy::{LazyMax, LazyMin, LazySum}; #[test] fn test_examples() { @@ -143,9 +150,9 @@ mod test { Box::new(LazyAggregate {}), Box::new(ToLazyGroupBy {}), Box::new(ExprAlias {}), - Box::new(LazyMin {}), - Box::new(LazyMax {}), - Box::new(LazySum {}), + Box::new(ExprMin {}), + Box::new(ExprMax {}), + Box::new(ExprSum {}), ]) } } diff --git a/crates/nu-command/src/dataframe/lazy/collect.rs b/crates/nu-command/src/dataframe/lazy/collect.rs index 9691434ed..bd3f3d236 100644 --- a/crates/nu-command/src/dataframe/lazy/collect.rs +++ b/crates/nu-command/src/dataframe/lazy/collect.rs @@ -4,7 +4,7 @@ use super::super::values::NuLazyFrame; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; #[derive(Clone)] @@ -12,7 +12,7 @@ pub struct LazyCollect; impl Command for LazyCollect { fn name(&self) -> &str { - "dfr collect" + "collect" } fn usage(&self) -> &str { @@ -26,7 +26,7 @@ impl Command for LazyCollect { fn examples(&self) -> Vec { vec![Example { description: "drop duplicates", - example: "[[a b]; [1 2] [3 4]] | dfr to-lazy | dfr collect", + example: "[[a b]; [1 2] [3 4]] | to-lazy | collect", result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -44,6 +44,14 @@ impl Command for LazyCollect { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, _engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/lazy/fetch.rs b/crates/nu-command/src/dataframe/lazy/fetch.rs index 2b0d76471..fec93e73d 100644 --- a/crates/nu-command/src/dataframe/lazy/fetch.rs +++ b/crates/nu-command/src/dataframe/lazy/fetch.rs @@ -4,7 +4,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; #[derive(Clone)] @@ -12,7 +12,7 @@ pub struct LazyFetch; impl Command for LazyFetch { fn name(&self) -> &str { - "dfr fetch" + "fetch" } fn usage(&self) -> &str { @@ -32,7 +32,7 @@ impl Command for LazyFetch { fn examples(&self) -> Vec { vec![Example { description: "Fetch a rows from the dataframe", - example: "[[a b]; [6 2] [4 2] [2 2]] | dfr to-df | dfr fetch 2", + example: "[[a b]; [6 2] [4 2] [2 2]] | to-df | fetch 2", result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -50,6 +50,14 @@ impl Command for LazyFetch { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/lazy/fill_na.rs b/crates/nu-command/src/dataframe/lazy/fill_na.rs index d6797a0f4..c5a66012f 100644 --- a/crates/nu-command/src/dataframe/lazy/fill_na.rs +++ b/crates/nu-command/src/dataframe/lazy/fill_na.rs @@ -3,7 +3,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, SyntaxShape, Type, Value, }; #[derive(Clone)] @@ -11,7 +11,7 @@ pub struct LazyFillNA; impl Command for LazyFillNA { fn name(&self) -> &str { - "dfr fill-na" + "fill-na" } fn usage(&self) -> &str { @@ -36,6 +36,14 @@ impl Command for LazyFillNA { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/lazy/fill_null.rs b/crates/nu-command/src/dataframe/lazy/fill_null.rs index 8f583b54f..154c37f54 100644 --- a/crates/nu-command/src/dataframe/lazy/fill_null.rs +++ b/crates/nu-command/src/dataframe/lazy/fill_null.rs @@ -3,7 +3,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; #[derive(Clone)] @@ -11,7 +11,7 @@ pub struct LazyFillNull; impl Command for LazyFillNull { fn name(&self) -> &str { - "dfr fill-null" + "fill-null" } fn usage(&self) -> &str { @@ -31,7 +31,7 @@ impl Command for LazyFillNull { fn examples(&self) -> Vec { vec![Example { description: "Fills the null values by 0", - example: "[1 2 2 3 3] | dfr to-df | dfr shift 2 | dfr fill-null 0", + example: "[1 2 2 3 3] | to-df | shift 2 | fill-null 0", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -49,6 +49,14 @@ impl Command for LazyFillNull { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/lazy/groupby.rs b/crates/nu-command/src/dataframe/lazy/groupby.rs index 494c548e2..1ecfec179 100644 --- a/crates/nu-command/src/dataframe/lazy/groupby.rs +++ b/crates/nu-command/src/dataframe/lazy/groupby.rs @@ -3,7 +3,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use polars::prelude::Expr; @@ -12,7 +12,7 @@ pub struct ToLazyGroupBy; impl Command for ToLazyGroupBy { fn name(&self) -> &str { - "dfr group-by" + "group-by" } fn usage(&self) -> &str { @@ -34,12 +34,12 @@ impl Command for ToLazyGroupBy { Example { description: "Group by and perform an aggregation", example: r#"[[a b]; [1 2] [1 4] [2 6] [2 4]] - | dfr to-df - | dfr group-by a - | dfr agg [ - ("b" | dfr min | dfr as "b_min") - ("b" | dfr max | dfr as "b_max") - ("b" | dfr sum | dfr as "b_sum") + | to-df + | group-by a + | agg [ + (col b | min | as "b_min") + (col b | max | as "b_max") + (col b | sum | as "b_sum") ]"#, result: Some( NuDataFrame::try_from_columns(vec![ @@ -67,14 +67,14 @@ impl Command for ToLazyGroupBy { Example { description: "Group by and perform an aggregation", example: r#"[[a b]; [1 2] [1 4] [2 6] [2 4]] - | dfr to-df - | dfr group-by a - | dfr agg [ - ("b" | dfr min | dfr as "b_min") - ("b" | dfr max | dfr as "b_max") - ("b" | dfr sum | dfr as "b_sum") + | to-lazy + | group-by a + | agg [ + (col b | min | as "b_min") + (col b | max | as "b_max") + (col b | sum | as "b_sum") ] - | dfr collect"#, + | collect"#, result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -101,6 +101,14 @@ impl Command for ToLazyGroupBy { ] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, @@ -143,9 +151,8 @@ impl Command for ToLazyGroupBy { mod test { use super::super::super::test_dataframe::test_dataframe; use super::*; - use crate::dataframe::expressions::ExprAlias; + use crate::dataframe::expressions::{ExprAlias, ExprMax, ExprMin, ExprSum}; use crate::dataframe::lazy::aggregate::LazyAggregate; - use crate::dataframe::lazy::{LazyMax, LazyMin, LazySum}; #[test] fn test_examples() { @@ -153,9 +160,9 @@ mod test { Box::new(LazyAggregate {}), Box::new(ToLazyGroupBy {}), Box::new(ExprAlias {}), - Box::new(LazyMin {}), - Box::new(LazyMax {}), - Box::new(LazySum {}), + Box::new(ExprMin {}), + Box::new(ExprMax {}), + Box::new(ExprSum {}), ]) } } diff --git a/crates/nu-command/src/dataframe/lazy/join.rs b/crates/nu-command/src/dataframe/lazy/join.rs index 71eecc03f..050f54b08 100644 --- a/crates/nu-command/src/dataframe/lazy/join.rs +++ b/crates/nu-command/src/dataframe/lazy/join.rs @@ -3,7 +3,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use polars::prelude::{Expr, JoinType}; @@ -12,7 +12,7 @@ pub struct LazyJoin; impl Command for LazyJoin { fn name(&self) -> &str { - "dfr join" + "join" } fn usage(&self) -> &str { @@ -45,9 +45,9 @@ impl Command for LazyJoin { vec![ Example { description: "Join two lazy dataframes", - example: r#"let df_a = ([[a b c];[1 "a" 0] [2 "b" 1] [1 "c" 2] [1 "c" 3]] | dfr to-lazy); - let df_b = ([["foo" "bar" "ham"];[1 "a" "let"] [2 "c" "var"] [3 "c" "const"]] | dfr to-lazy); - $df_a | dfr join $df_b a foo | dfr collect"#, + example: r#"let df_a = ([[a b c];[1 "a" 0] [2 "b" 1] [1 "c" 2] [1 "c" 3]] | to-lazy); + let df_b = ([["foo" "bar" "ham"];[1 "a" "let"] [2 "c" "var"] [3 "c" "const"]] | to-lazy); + $df_a | join $df_b a foo | collect"#, result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -102,9 +102,9 @@ impl Command for LazyJoin { }, Example { description: "Join one eager dataframe with a lazy dataframe", - example: r#"let df_a = ([[a b c];[1 "a" 0] [2 "b" 1] [1 "c" 2] [1 "c" 3]] | dfr to-df); - let df_b = ([["foo" "bar" "ham"];[1 "a" "let"] [2 "c" "var"] [3 "c" "const"]] | dfr to-lazy); - $df_a | dfr join $df_b a foo"#, + example: r#"let df_a = ([[a b c];[1 "a" 0] [2 "b" 1] [1 "c" 2] [1 "c" 3]] | to-df); + let df_b = ([["foo" "bar" "ham"];[1 "a" "let"] [2 "c" "var"] [3 "c" "const"]] | to-lazy); + $df_a | join $df_b a foo"#, result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -160,6 +160,14 @@ impl Command for LazyJoin { ] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/lazy/macro_commands.rs b/crates/nu-command/src/dataframe/lazy/macro_commands.rs index 7e4cd613a..1a36e3a23 100644 --- a/crates/nu-command/src/dataframe/lazy/macro_commands.rs +++ b/crates/nu-command/src/dataframe/lazy/macro_commands.rs @@ -1,11 +1,11 @@ /// Definition of multiple lazyframe commands using a macro rule /// All of these commands have an identical body and only require /// to have a change in the name, description and function -use crate::dataframe::values::{Column, NuDataFrame, NuExpression, NuLazyFrame}; +use crate::dataframe::values::{Column, NuDataFrame, NuLazyFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; macro_rules! lazy_command { @@ -30,6 +30,14 @@ macro_rules! lazy_command { $examples } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, _engine_state: &EngineState, @@ -61,11 +69,11 @@ macro_rules! lazy_command { // Expands to a command definition for reverse lazy_command!( LazyReverse, - "dfr reverse", + "reverse", "Reverses the LazyFrame", vec![Example { description: "Reverses the dataframe", - example: "[[a b]; [6 2] [4 2] [2 2]] | dfr to-df | dfr reverse", + example: "[[a b]; [6 2] [4 2] [2 2]] | to-df | reverse", result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -89,398 +97,167 @@ lazy_command!( // Expands to a command definition for cache lazy_command!( LazyCache, - "dfr cache", + "cache", "Caches operations in a new LazyFrame", vec![Example { description: "Caches the result into a new LazyFrame", - example: "[[a b]; [6 2] [4 2] [2 2]] | dfr to-df | dfr reverse | dfr cache", + example: "[[a b]; [6 2] [4 2] [2 2]] | to-df | reverse | cache", result: None, }], cache, test_cache ); -// Creates a command that may result in a lazy frame operation or -// lazy frame expression -macro_rules! lazy_expr_command { - ($command: ident, $name: expr, $desc: expr, $examples: expr, $func: ident, $test: ident) => { - #[derive(Clone)] - pub struct $command; - - impl Command for $command { - fn name(&self) -> &str { - $name - } - - fn usage(&self) -> &str { - $desc - } - - fn signature(&self) -> Signature { - Signature::build(self.name()) - .category(Category::Custom("lazyframe or expression".into())) - } - - fn examples(&self) -> Vec { - $examples - } - - fn run( - &self, - _engine_state: &EngineState, - _stack: &mut Stack, - call: &Call, - input: PipelineData, - ) -> Result { - let value = input.into_value(call.head); - - if NuExpression::can_downcast(&value) { - let expr = NuExpression::try_from_value(value)?; - let expr: NuExpression = expr.into_polars().$func().into(); - - Ok(PipelineData::Value( - NuExpression::into_value(expr, call.head), - None, - )) - } else { - let lazy = NuLazyFrame::try_from_value(value)?; - let lazy = NuLazyFrame::new(lazy.from_eager, lazy.into_polars().$func()); - - Ok(PipelineData::Value(lazy.into_value(call.head)?, None)) - } - } - } - - #[cfg(test)] - mod $test { - use super::super::super::test_dataframe::test_dataframe; - use super::*; - use crate::dataframe::lazy::aggregate::LazyAggregate; - use crate::dataframe::lazy::groupby::ToLazyGroupBy; - - #[test] - fn test_examples() { - test_dataframe(vec![ - Box::new($command {}), - Box::new(LazyAggregate {}), - Box::new(ToLazyGroupBy {}), - ]) - } - } - }; -} - // LazyMax command // Expands to a command definition for max aggregation -lazy_expr_command!( +lazy_command!( LazyMax, - "dfr max", - "Aggregates columns to their max value or creates a max expression", - vec![ - Example { - description: "Max value from columns in a dataframe", - example: "[[a b]; [6 2] [1 4] [4 1]] | dfr to-df | dfr max", - result: Some( - NuDataFrame::try_from_columns(vec![ - Column::new("a".to_string(), vec![Value::test_int(6)],), - Column::new("b".to_string(), vec![Value::test_int(4)],), - ]) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }, - Example { - description: "Max aggregation for a group by", - example: r#"[[a b]; [one 2] [one 4] [two 1]] - | dfr to-df - | dfr group-by a - | dfr agg ("b" | dfr max)"#, - result: Some( - NuDataFrame::try_from_columns(vec![ - Column::new( - "a".to_string(), - vec![Value::test_string("one"), Value::test_string("two")], - ), - Column::new( - "b".to_string(), - vec![Value::test_int(4), Value::test_int(1)], - ), - ]) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }, - ], + "max", + "Aggregates columns to their max value", + vec![Example { + description: "Max value from columns in a dataframe", + example: "[[a b]; [6 2] [1 4] [4 1]] | to-df | max", + result: Some( + NuDataFrame::try_from_columns(vec![ + Column::new("a".to_string(), vec![Value::test_int(6)],), + Column::new("b".to_string(), vec![Value::test_int(4)],), + ]) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + },], max, test_max ); // LazyMin command // Expands to a command definition for min aggregation -lazy_expr_command!( +lazy_command!( LazyMin, - "dfr min", - "Aggregates columns to their min value or creates a min expression", - vec![ - Example { - description: "Min value from columns in a dataframe", - example: "[[a b]; [6 2] [1 4] [4 1]] | dfr to-df | dfr min", - result: Some( - NuDataFrame::try_from_columns(vec![ - Column::new("a".to_string(), vec![Value::test_int(1)],), - Column::new("b".to_string(), vec![Value::test_int(1)],), - ]) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }, - Example { - description: "Min aggregation for a group by", - example: r#"[[a b]; [one 2] [one 4] [two 1]] - | dfr to-df - | dfr group-by a - | dfr agg ("b" | dfr min)"#, - result: Some( - NuDataFrame::try_from_columns(vec![ - Column::new( - "a".to_string(), - vec![Value::test_string("one"), Value::test_string("two")], - ), - Column::new( - "b".to_string(), - vec![Value::test_int(2), Value::test_int(1)], - ), - ]) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }, - ], + "min", + "Aggregates columns to their min value", + vec![Example { + description: "Min value from columns in a dataframe", + example: "[[a b]; [6 2] [1 4] [4 1]] | to-df | min", + result: Some( + NuDataFrame::try_from_columns(vec![ + Column::new("a".to_string(), vec![Value::test_int(1)],), + Column::new("b".to_string(), vec![Value::test_int(1)],), + ]) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + },], min, test_min ); // LazySum command // Expands to a command definition for sum aggregation -lazy_expr_command!( +lazy_command!( LazySum, - "dfr sum", - "Aggregates columns to their sum value or creates a sum expression for an aggregation", - vec![ - Example { - description: "Sums all columns in a dataframe", - example: "[[a b]; [6 2] [1 4] [4 1]] | dfr to-df | dfr sum", - result: Some( - NuDataFrame::try_from_columns(vec![ - Column::new("a".to_string(), vec![Value::test_int(11)],), - Column::new("b".to_string(), vec![Value::test_int(7)],), - ]) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }, - Example { - description: "Sum aggregation for a group by", - example: r#"[[a b]; [one 2] [one 4] [two 1]] - | dfr to-df - | dfr group-by a - | dfr agg ("b" | dfr sum)"#, - result: Some( - NuDataFrame::try_from_columns(vec![ - Column::new( - "a".to_string(), - vec![Value::test_string("one"), Value::test_string("two")], - ), - Column::new( - "b".to_string(), - vec![Value::test_int(6), Value::test_int(1)], - ), - ]) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }, - ], + "sum", + "Aggregates columns to their sum value", + vec![Example { + description: "Sums all columns in a dataframe", + example: "[[a b]; [6 2] [1 4] [4 1]] | to-df | sum", + result: Some( + NuDataFrame::try_from_columns(vec![ + Column::new("a".to_string(), vec![Value::test_int(11)],), + Column::new("b".to_string(), vec![Value::test_int(7)],), + ]) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + },], sum, test_sum ); // LazyMean command // Expands to a command definition for mean aggregation -lazy_expr_command!( +lazy_command!( LazyMean, - "dfr mean", - "Aggregates columns to their mean value or creates a mean expression for an aggregation", - vec![ - Example { - description: "Mean value from columns in a dataframe", - example: "[[a b]; [6 2] [4 2] [2 2]] | dfr to-df | dfr mean", - result: Some( - NuDataFrame::try_from_columns(vec![ - Column::new("a".to_string(), vec![Value::test_float(4.0)],), - Column::new("b".to_string(), vec![Value::test_float(2.0)],), - ]) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }, - Example { - description: "Mean aggregation for a group by", - example: r#"[[a b]; [one 2] [one 4] [two 1]] - | dfr to-df - | dfr group-by a - | dfr agg ("b" | dfr mean)"#, - result: Some( - NuDataFrame::try_from_columns(vec![ - Column::new( - "a".to_string(), - vec![Value::test_string("one"), Value::test_string("two")], - ), - Column::new( - "b".to_string(), - vec![Value::test_float(3.0), Value::test_float(1.0)], - ), - ]) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }, - ], + "mean", + "Aggregates columns to their mean value", + vec![Example { + description: "Mean value from columns in a dataframe", + example: "[[a b]; [6 2] [4 2] [2 2]] | to-df | mean", + result: Some( + NuDataFrame::try_from_columns(vec![ + Column::new("a".to_string(), vec![Value::test_float(4.0)],), + Column::new("b".to_string(), vec![Value::test_float(2.0)],), + ]) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + },], mean, test_mean ); // LazyMedian command // Expands to a command definition for median aggregation -lazy_expr_command!( +lazy_command!( LazyMedian, - "dfr median", - "Aggregates columns to their median value or creates a median expression for an aggregation", - vec![ - Example { - description: "Median value from columns in a dataframe", - example: "[[a b]; [6 2] [4 2] [2 2]] | dfr to-df | dfr median", - result: Some( - NuDataFrame::try_from_columns(vec![ - Column::new("a".to_string(), vec![Value::test_float(4.0)],), - Column::new("b".to_string(), vec![Value::test_float(2.0)],), - ]) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }, - Example { - description: "Median aggregation for a group by", - example: r#"[[a b]; [one 2] [one 4] [two 1]] - | dfr to-df - | dfr group-by a - | dfr agg ("b" | dfr median)"#, - result: Some( - NuDataFrame::try_from_columns(vec![ - Column::new( - "a".to_string(), - vec![Value::test_string("one"), Value::test_string("two")], - ), - Column::new( - "b".to_string(), - vec![Value::test_float(3.0), Value::test_float(1.0)], - ), - ]) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }, - ], + "median", + "Aggregates columns to their median value", + vec![Example { + description: "Median value from columns in a dataframe", + example: "[[a b]; [6 2] [4 2] [2 2]] | to-df | median", + result: Some( + NuDataFrame::try_from_columns(vec![ + Column::new("a".to_string(), vec![Value::test_float(4.0)],), + Column::new("b".to_string(), vec![Value::test_float(2.0)],), + ]) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + },], median, test_median ); // LazyStd command // Expands to a command definition for std aggregation -lazy_expr_command!( +lazy_command!( LazyStd, - "dfr std", - "Aggregates columns to their std value or creates a std expression for an aggregation", - vec![ - Example { - description: "Std value from columns in a dataframe", - example: "[[a b]; [6 2] [4 2] [2 2]] | dfr to-df | dfr std", - result: Some( - NuDataFrame::try_from_columns(vec![ - Column::new("a".to_string(), vec![Value::test_float(2.0)],), - Column::new("b".to_string(), vec![Value::test_float(0.0)],), - ]) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }, - Example { - description: "Std aggregation for a group by", - example: r#"[[a b]; [one 2] [one 2] [two 1] [two 1]] - | dfr to-df - | dfr group-by a - | dfr agg ("b" | dfr std)"#, - result: Some( - NuDataFrame::try_from_columns(vec![ - Column::new( - "a".to_string(), - vec![Value::test_string("one"), Value::test_string("two")], - ), - Column::new( - "b".to_string(), - vec![Value::test_float(0.0), Value::test_float(0.0)], - ), - ]) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }, - ], + "std", + "Aggregates columns to their std value", + vec![Example { + description: "Std value from columns in a dataframe", + example: "[[a b]; [6 2] [4 2] [2 2]] | to-df | std", + result: Some( + NuDataFrame::try_from_columns(vec![ + Column::new("a".to_string(), vec![Value::test_float(2.0)],), + Column::new("b".to_string(), vec![Value::test_float(0.0)],), + ]) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + },], std, test_std ); // LazyVar command // Expands to a command definition for var aggregation -lazy_expr_command!( +lazy_command!( LazyVar, - "dfr var", - "Aggregates columns to their var value or create a var expression for an aggregation", - vec![ - Example { - description: "Var value from columns in a dataframe", - example: "[[a b]; [6 2] [4 2] [2 2]] | dfr to-df | dfr var", - result: Some( - NuDataFrame::try_from_columns(vec![ - Column::new("a".to_string(), vec![Value::test_float(4.0)],), - Column::new("b".to_string(), vec![Value::test_float(0.0)],), - ]) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }, - Example { - description: "Var aggregation for a group by", - example: r#"[[a b]; [one 2] [one 2] [two 1] [two 1]] - | dfr to-df - | dfr group-by a - | dfr agg ("b" | dfr var)"#, - result: Some( - NuDataFrame::try_from_columns(vec![ - Column::new( - "a".to_string(), - vec![Value::test_string("one"), Value::test_string("two")], - ), - Column::new( - "b".to_string(), - vec![Value::test_float(0.0), Value::test_float(0.0)], - ), - ]) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }, - ], + "var", + "Aggregates columns to their var value", + vec![Example { + description: "Var value from columns in a dataframe", + example: "[[a b]; [6 2] [4 2] [2 2]] | to-df | var", + result: Some( + NuDataFrame::try_from_columns(vec![ + Column::new("a".to_string(), vec![Value::test_float(4.0)],), + Column::new("b".to_string(), vec![Value::test_float(0.0)],), + ]) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + },], var, test_var ); diff --git a/crates/nu-command/src/dataframe/lazy/mod.rs b/crates/nu-command/src/dataframe/lazy/mod.rs index 3b9548f07..50c77f279 100644 --- a/crates/nu-command/src/dataframe/lazy/mod.rs +++ b/crates/nu-command/src/dataframe/lazy/mod.rs @@ -1,9 +1,9 @@ -mod aggregate; +pub mod aggregate; mod collect; mod fetch; mod fill_na; mod fill_null; -mod groupby; +pub mod groupby; mod join; mod macro_commands; mod quantile; diff --git a/crates/nu-command/src/dataframe/lazy/quantile.rs b/crates/nu-command/src/dataframe/lazy/quantile.rs index 6726ab56c..3b34ff1ac 100644 --- a/crates/nu-command/src/dataframe/lazy/quantile.rs +++ b/crates/nu-command/src/dataframe/lazy/quantile.rs @@ -1,9 +1,9 @@ -use crate::dataframe::values::{Column, NuDataFrame, NuExpression, NuLazyFrame}; +use crate::dataframe::values::{Column, NuDataFrame, NuLazyFrame}; use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use polars::prelude::QuantileInterpolOptions; @@ -12,7 +12,7 @@ pub struct LazyQuantile; impl Command for LazyQuantile { fn name(&self) -> &str { - "dfr quantile" + "quantile" } fn usage(&self) -> &str { @@ -30,41 +30,26 @@ impl Command for LazyQuantile { } fn examples(&self) -> Vec { - vec![ - Example { - description: "quantile value from columns in a dataframe", - example: "[[a b]; [6 2] [1 4] [4 1]] | dfr to-df | dfr quantile 0.5", - result: Some( - NuDataFrame::try_from_columns(vec![ - Column::new("a".to_string(), vec![Value::test_float(4.0)]), - Column::new("b".to_string(), vec![Value::test_float(2.0)]), - ]) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }, - Example { - description: "Quantile aggregation for a group by", - example: r#"[[a b]; [one 2] [one 4] [two 1]] - | dfr to-df - | dfr group-by a - | dfr agg ("b" | dfr quantile 0.5)"#, - result: Some( - NuDataFrame::try_from_columns(vec![ - Column::new( - "a".to_string(), - vec![Value::test_string("one"), Value::test_string("two")], - ), - Column::new( - "b".to_string(), - vec![Value::test_float(4.0), Value::test_float(1.0)], - ), - ]) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }, - ] + vec![Example { + description: "quantile value from columns in a dataframe", + example: "[[a b]; [6 2] [1 4] [4 1]] | to-df | quantile 0.5", + result: Some( + NuDataFrame::try_from_columns(vec![ + Column::new("a".to_string(), vec![Value::test_float(4.0)]), + Column::new("b".to_string(), vec![Value::test_float(2.0)]), + ]) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + }] + } + + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) } fn run( @@ -77,27 +62,14 @@ impl Command for LazyQuantile { let value = input.into_value(call.head); let quantile: f64 = call.req(engine_state, stack, 0)?; - if NuExpression::can_downcast(&value) { - let expr = NuExpression::try_from_value(value)?; - let expr: NuExpression = expr - .into_polars() - .quantile(quantile, QuantileInterpolOptions::default()) - .into(); + let lazy = NuLazyFrame::try_from_value(value)?; + let lazy = NuLazyFrame::new( + lazy.from_eager, + lazy.into_polars() + .quantile(quantile, QuantileInterpolOptions::default()), + ); - Ok(PipelineData::Value( - NuExpression::into_value(expr, call.head), - None, - )) - } else { - let lazy = NuLazyFrame::try_from_value(value)?; - let lazy = NuLazyFrame::new( - lazy.from_eager, - lazy.into_polars() - .quantile(quantile, QuantileInterpolOptions::default()), - ); - - Ok(PipelineData::Value(lazy.into_value(call.head)?, None)) - } + Ok(PipelineData::Value(lazy.into_value(call.head)?, None)) } } @@ -105,15 +77,9 @@ impl Command for LazyQuantile { mod test { use super::super::super::test_dataframe::test_dataframe; use super::*; - use crate::dataframe::lazy::aggregate::LazyAggregate; - use crate::dataframe::lazy::groupby::ToLazyGroupBy; #[test] fn test_examples() { - test_dataframe(vec![ - Box::new(LazyQuantile {}), - Box::new(LazyAggregate {}), - Box::new(ToLazyGroupBy {}), - ]) + test_dataframe(vec![Box::new(LazyQuantile {})]) } } diff --git a/crates/nu-command/src/dataframe/lazy/select.rs b/crates/nu-command/src/dataframe/lazy/select.rs index f336e4665..f98a3511b 100644 --- a/crates/nu-command/src/dataframe/lazy/select.rs +++ b/crates/nu-command/src/dataframe/lazy/select.rs @@ -4,7 +4,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use polars::prelude::Expr; @@ -13,7 +13,7 @@ pub struct LazySelect; impl Command for LazySelect { fn name(&self) -> &str { - "dfr select" + "select" } fn usage(&self) -> &str { @@ -33,7 +33,7 @@ impl Command for LazySelect { fn examples(&self) -> Vec { vec![Example { description: "Select a column from the dataframe", - example: "[[a b]; [6 2] [4 2] [2 2]] | dfr to-df | dfr select a", + example: "[[a b]; [6 2] [4 2] [2 2]] | to-df | select a", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "a".to_string(), @@ -45,6 +45,14 @@ impl Command for LazySelect { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/lazy/sort_by_expr.rs b/crates/nu-command/src/dataframe/lazy/sort_by_expr.rs index f11d5db37..079bf545a 100644 --- a/crates/nu-command/src/dataframe/lazy/sort_by_expr.rs +++ b/crates/nu-command/src/dataframe/lazy/sort_by_expr.rs @@ -4,7 +4,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; #[derive(Clone)] @@ -12,7 +12,7 @@ pub struct LazySortBy; impl Command for LazySortBy { fn name(&self) -> &str { - "dfr sort-by" + "sort-by" } fn usage(&self) -> &str { @@ -39,7 +39,7 @@ impl Command for LazySortBy { vec![ Example { description: "Sort dataframe by one column", - example: "[[a b]; [6 2] [1 4] [4 1]] | dfr to-df | dfr sort-by a", + example: "[[a b]; [6 2] [1 4] [4 1]] | to-df | sort-by a", result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -57,8 +57,7 @@ impl Command for LazySortBy { }, Example { description: "Sort column using two columns", - example: - "[[a b]; [6 2] [1 1] [1 4] [2 4]] | dfr to-df | dfr sort-by [a b] -r [false true]", + example: "[[a b]; [6 2] [1 1] [1 4] [2 4]] | to-df | sort-by [a b] -r [false true]", result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -87,6 +86,14 @@ impl Command for LazySortBy { ] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/lazy/to_lazy.rs b/crates/nu-command/src/dataframe/lazy/to_lazy.rs index 4e0158036..22363dd8a 100644 --- a/crates/nu-command/src/dataframe/lazy/to_lazy.rs +++ b/crates/nu-command/src/dataframe/lazy/to_lazy.rs @@ -3,7 +3,7 @@ use super::super::values::{NuDataFrame, NuLazyFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Value, + Category, Example, PipelineData, ShellError, Signature, Type, Value, }; #[derive(Clone)] @@ -11,7 +11,7 @@ pub struct ToLazyFrame; impl Command for ToLazyFrame { fn name(&self) -> &str { - "dfr to-lazy" + "to-lazy" } fn usage(&self) -> &str { @@ -25,11 +25,19 @@ impl Command for ToLazyFrame { fn examples(&self) -> Vec { vec![Example { description: "Takes a dictionary and creates a lazy dataframe", - example: "[[a b];[1 2] [3 4]] | dfr to-df | dfl to-lazy", + example: "[[a b];[1 2] [3 4]] | to-lazy", result: None, }] } + fn input_type(&self) -> Type { + Type::Any + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, _engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/all_false.rs b/crates/nu-command/src/dataframe/series/all_false.rs index 67982f690..ef60628af 100644 --- a/crates/nu-command/src/dataframe/series/all_false.rs +++ b/crates/nu-command/src/dataframe/series/all_false.rs @@ -3,7 +3,7 @@ use super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; #[derive(Clone)] @@ -11,7 +11,7 @@ pub struct AllFalse; impl Command for AllFalse { fn name(&self) -> &str { - "dfr all-false" + "all-false" } fn usage(&self) -> &str { @@ -26,7 +26,7 @@ impl Command for AllFalse { vec![ Example { description: "Returns true if all values are false", - example: "[false false false] | dfr to-df | dfr all-false", + example: "[false false false] | to-df | all-false", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "all_false".to_string(), @@ -38,9 +38,9 @@ impl Command for AllFalse { }, Example { description: "Checks the result from a comparison", - example: r#"let s = ([5 6 2 10] | dfr to-df); + example: r#"let s = ([5 6 2 10] | to-df); let res = ($s > 9); - $res | dfr all-false"#, + $res | all-false"#, result: Some( NuDataFrame::try_from_columns(vec![Column::new( "all_false".to_string(), @@ -53,6 +53,14 @@ impl Command for AllFalse { ] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/all_true.rs b/crates/nu-command/src/dataframe/series/all_true.rs index 380ba7ef7..3f83002e6 100644 --- a/crates/nu-command/src/dataframe/series/all_true.rs +++ b/crates/nu-command/src/dataframe/series/all_true.rs @@ -3,7 +3,7 @@ use super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; #[derive(Clone)] @@ -11,7 +11,7 @@ pub struct AllTrue; impl Command for AllTrue { fn name(&self) -> &str { - "dfr all-true" + "all-true" } fn usage(&self) -> &str { @@ -26,7 +26,7 @@ impl Command for AllTrue { vec![ Example { description: "Returns true if all values are true", - example: "[true true true] | dfr to-df | dfr all-true", + example: "[true true true] | to-df | all-true", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "all_true".to_string(), @@ -38,9 +38,9 @@ impl Command for AllTrue { }, Example { description: "Checks the result from a comparison", - example: r#"let s = ([5 6 2 8] | dfr to-df); + example: r#"let s = ([5 6 2 8] | to-df); let res = ($s > 9); - $res | dfr all-true"#, + $res | all-true"#, result: Some( NuDataFrame::try_from_columns(vec![Column::new( "all_true".to_string(), @@ -53,6 +53,14 @@ impl Command for AllTrue { ] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/arg_max.rs b/crates/nu-command/src/dataframe/series/arg_max.rs index b3307ca88..5e915ddfc 100644 --- a/crates/nu-command/src/dataframe/series/arg_max.rs +++ b/crates/nu-command/src/dataframe/series/arg_max.rs @@ -3,7 +3,7 @@ use super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use polars::prelude::{IntoSeries, NewChunkedArray, UInt32Chunked}; @@ -12,7 +12,7 @@ pub struct ArgMax; impl Command for ArgMax { fn name(&self) -> &str { - "dfr arg-max" + "arg-max" } fn usage(&self) -> &str { @@ -26,7 +26,7 @@ impl Command for ArgMax { fn examples(&self) -> Vec { vec![Example { description: "Returns index for max value", - example: "[1 3 2] | dfr to-df | dfr arg-max", + example: "[1 3 2] | to-df | arg-max", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "arg_max".to_string(), @@ -38,6 +38,14 @@ impl Command for ArgMax { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/arg_min.rs b/crates/nu-command/src/dataframe/series/arg_min.rs index 8dccc8d75..d362647fc 100644 --- a/crates/nu-command/src/dataframe/series/arg_min.rs +++ b/crates/nu-command/src/dataframe/series/arg_min.rs @@ -3,7 +3,7 @@ use super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use polars::prelude::{IntoSeries, NewChunkedArray, UInt32Chunked}; @@ -12,7 +12,7 @@ pub struct ArgMin; impl Command for ArgMin { fn name(&self) -> &str { - "dfr arg-min" + "arg-min" } fn usage(&self) -> &str { @@ -26,7 +26,7 @@ impl Command for ArgMin { fn examples(&self) -> Vec { vec![Example { description: "Returns index for min value", - example: "[1 3 2] | dfr to-df | dfr arg-min", + example: "[1 3 2] | to-df | arg-min", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "arg_min".to_string(), @@ -38,6 +38,14 @@ impl Command for ArgMin { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/cumulative.rs b/crates/nu-command/src/dataframe/series/cumulative.rs index 8c25b5d5f..2c7537965 100644 --- a/crates/nu-command/src/dataframe/series/cumulative.rs +++ b/crates/nu-command/src/dataframe/series/cumulative.rs @@ -4,7 +4,8 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Type, + Value, }; use polars::prelude::{DataType, IntoSeries}; @@ -44,7 +45,7 @@ pub struct Cumulative; impl Command for Cumulative { fn name(&self) -> &str { - "dfr cumulative" + "cumulative" } fn usage(&self) -> &str { @@ -61,7 +62,7 @@ impl Command for Cumulative { fn examples(&self) -> Vec { vec![Example { description: "Cumulative sum for a series", - example: "[1 2 3 4 5] | dfr to-df | dfr cumulative sum", + example: "[1 2 3 4 5] | to-df | cumulative sum", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0_cumulative_sum".to_string(), @@ -79,6 +80,14 @@ impl Command for Cumulative { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/date/as_date.rs b/crates/nu-command/src/dataframe/series/date/as_date.rs index e12260a6e..15dc05d90 100644 --- a/crates/nu-command/src/dataframe/series/date/as_date.rs +++ b/crates/nu-command/src/dataframe/series/date/as_date.rs @@ -4,7 +4,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, SyntaxShape, + Category, Example, PipelineData, ShellError, Signature, SyntaxShape, Type, }; use polars::prelude::{IntoSeries, Utf8Methods}; @@ -13,7 +13,7 @@ pub struct AsDate; impl Command for AsDate { fn name(&self) -> &str { - "dfr as-date" + "as-date" } fn usage(&self) -> &str { @@ -37,11 +37,19 @@ impl Command for AsDate { fn examples(&self) -> Vec { vec![Example { description: "Converts string to date", - example: r#"["2021-12-30" "2021-12-31"] | dfr to-df | dfr as-datetime "%Y-%m-%d""#, + example: r#"["2021-12-30" "2021-12-31"] | to-df | as-datetime "%Y-%m-%d""#, result: None, }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/date/as_datetime.rs b/crates/nu-command/src/dataframe/series/date/as_datetime.rs index e14fc5432..153891cc3 100644 --- a/crates/nu-command/src/dataframe/series/date/as_datetime.rs +++ b/crates/nu-command/src/dataframe/series/date/as_datetime.rs @@ -5,7 +5,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use polars::prelude::{IntoSeries, TimeUnit, Utf8Methods}; @@ -14,7 +14,7 @@ pub struct AsDateTime; impl Command for AsDateTime { fn name(&self) -> &str { - "dfr as-datetime" + "as-datetime" } fn usage(&self) -> &str { @@ -46,7 +46,7 @@ impl Command for AsDateTime { fn examples(&self) -> Vec { vec![Example { description: "Converts string to datetime", - example: r#"["2021-12-30 00:00:00" "2021-12-31 00:00:00"] | dfr to-df | dfr as-datetime "%Y-%m-%d %H:%M:%S""#, + example: r#"["2021-12-30 00:00:00" "2021-12-31 00:00:00"] | to-df | as-datetime "%Y-%m-%d %H:%M:%S""#, result: Some( NuDataFrame::try_from_columns(vec![Column::new( "datetime".to_string(), @@ -75,6 +75,14 @@ impl Command for AsDateTime { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/date/get_day.rs b/crates/nu-command/src/dataframe/series/date/get_day.rs index b3db0d568..9189f99e6 100644 --- a/crates/nu-command/src/dataframe/series/date/get_day.rs +++ b/crates/nu-command/src/dataframe/series/date/get_day.rs @@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use polars::prelude::{DatetimeMethods, IntoSeries}; @@ -12,7 +12,7 @@ pub struct GetDay; impl Command for GetDay { fn name(&self) -> &str { - "dfr get-day" + "get-day" } fn usage(&self) -> &str { @@ -27,8 +27,8 @@ impl Command for GetDay { vec![Example { description: "Returns day from a date", example: r#"let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC'); - let df = ([$dt $dt] | dfr to-df); - $df | dfr get-day"#, + let df = ([$dt $dt] | to-df); + $df | get-day"#, result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -40,6 +40,14 @@ impl Command for GetDay { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/date/get_hour.rs b/crates/nu-command/src/dataframe/series/date/get_hour.rs index deda7edb4..84d0a3d93 100644 --- a/crates/nu-command/src/dataframe/series/date/get_hour.rs +++ b/crates/nu-command/src/dataframe/series/date/get_hour.rs @@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use polars::prelude::{DatetimeMethods, IntoSeries}; @@ -12,7 +12,7 @@ pub struct GetHour; impl Command for GetHour { fn name(&self) -> &str { - "dfr get-hour" + "get-hour" } fn usage(&self) -> &str { @@ -27,8 +27,8 @@ impl Command for GetHour { vec![Example { description: "Returns hour from a date", example: r#"let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC'); - let df = ([$dt $dt] | dfr to-df); - $df | dfr get-hour"#, + let df = ([$dt $dt] | to-df); + $df | get-hour"#, result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -40,6 +40,14 @@ impl Command for GetHour { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/date/get_minute.rs b/crates/nu-command/src/dataframe/series/date/get_minute.rs index 3a1133e1e..cb4ad1d15 100644 --- a/crates/nu-command/src/dataframe/series/date/get_minute.rs +++ b/crates/nu-command/src/dataframe/series/date/get_minute.rs @@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use polars::prelude::{DatetimeMethods, IntoSeries}; @@ -12,7 +12,7 @@ pub struct GetMinute; impl Command for GetMinute { fn name(&self) -> &str { - "dfr get-minute" + "get-minute" } fn usage(&self) -> &str { @@ -27,8 +27,8 @@ impl Command for GetMinute { vec![Example { description: "Returns minute from a date", example: r#"let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC'); - let df = ([$dt $dt] | dfr to-df); - $df | dfr get-minute"#, + let df = ([$dt $dt] | to-df); + $df | get-minute"#, result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -40,6 +40,14 @@ impl Command for GetMinute { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/date/get_month.rs b/crates/nu-command/src/dataframe/series/date/get_month.rs index e6e842680..a2bcb3bb1 100644 --- a/crates/nu-command/src/dataframe/series/date/get_month.rs +++ b/crates/nu-command/src/dataframe/series/date/get_month.rs @@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use polars::prelude::{DatetimeMethods, IntoSeries}; @@ -12,7 +12,7 @@ pub struct GetMonth; impl Command for GetMonth { fn name(&self) -> &str { - "dfr get-month" + "get-month" } fn usage(&self) -> &str { @@ -27,8 +27,8 @@ impl Command for GetMonth { vec![Example { description: "Returns month from a date", example: r#"let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC'); - let df = ([$dt $dt] | dfr to-df); - $df | dfr get-month"#, + let df = ([$dt $dt] | to-df); + $df | get-month"#, result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -40,6 +40,14 @@ impl Command for GetMonth { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/date/get_nanosecond.rs b/crates/nu-command/src/dataframe/series/date/get_nanosecond.rs index 3b6ea1e11..d614ef862 100644 --- a/crates/nu-command/src/dataframe/series/date/get_nanosecond.rs +++ b/crates/nu-command/src/dataframe/series/date/get_nanosecond.rs @@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use polars::prelude::{DatetimeMethods, IntoSeries}; @@ -12,7 +12,7 @@ pub struct GetNanosecond; impl Command for GetNanosecond { fn name(&self) -> &str { - "dfr get-nanosecond" + "get-nanosecond" } fn usage(&self) -> &str { @@ -27,8 +27,8 @@ impl Command for GetNanosecond { vec![Example { description: "Returns nanosecond from a date", example: r#"let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC'); - let df = ([$dt $dt] | dfr to-df); - $df | dfr get-nanosecond"#, + let df = ([$dt $dt] | to-df); + $df | get-nanosecond"#, result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -40,6 +40,14 @@ impl Command for GetNanosecond { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/date/get_ordinal.rs b/crates/nu-command/src/dataframe/series/date/get_ordinal.rs index 088a309a7..ab4dde1e0 100644 --- a/crates/nu-command/src/dataframe/series/date/get_ordinal.rs +++ b/crates/nu-command/src/dataframe/series/date/get_ordinal.rs @@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use polars::prelude::{DatetimeMethods, IntoSeries}; @@ -12,7 +12,7 @@ pub struct GetOrdinal; impl Command for GetOrdinal { fn name(&self) -> &str { - "dfr get-ordinal" + "get-ordinal" } fn usage(&self) -> &str { @@ -27,8 +27,8 @@ impl Command for GetOrdinal { vec![Example { description: "Returns ordinal from a date", example: r#"let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC'); - let df = ([$dt $dt] | dfr to-df); - $df | dfr get-ordinal"#, + let df = ([$dt $dt] | to-df); + $df | get-ordinal"#, result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -40,6 +40,14 @@ impl Command for GetOrdinal { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/date/get_second.rs b/crates/nu-command/src/dataframe/series/date/get_second.rs index da69832a1..dbbf6b301 100644 --- a/crates/nu-command/src/dataframe/series/date/get_second.rs +++ b/crates/nu-command/src/dataframe/series/date/get_second.rs @@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use polars::prelude::{DatetimeMethods, IntoSeries}; @@ -12,7 +12,7 @@ pub struct GetSecond; impl Command for GetSecond { fn name(&self) -> &str { - "dfr get-second" + "get-second" } fn usage(&self) -> &str { @@ -27,8 +27,8 @@ impl Command for GetSecond { vec![Example { description: "Returns second from a date", example: r#"let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC'); - let df = ([$dt $dt] | dfr to-df); - $df | dfr get-second"#, + let df = ([$dt $dt] | to-df); + $df | get-second"#, result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -40,6 +40,14 @@ impl Command for GetSecond { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/date/get_week.rs b/crates/nu-command/src/dataframe/series/date/get_week.rs index 27402492d..124b1ca3d 100644 --- a/crates/nu-command/src/dataframe/series/date/get_week.rs +++ b/crates/nu-command/src/dataframe/series/date/get_week.rs @@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use polars::prelude::{DatetimeMethods, IntoSeries}; @@ -12,7 +12,7 @@ pub struct GetWeek; impl Command for GetWeek { fn name(&self) -> &str { - "dfr get-week" + "get-week" } fn usage(&self) -> &str { @@ -27,8 +27,8 @@ impl Command for GetWeek { vec![Example { description: "Returns week from a date", example: r#"let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC'); - let df = ([$dt $dt] | dfr to-df); - $df | dfr get-week"#, + let df = ([$dt $dt] | to-df); + $df | get-week"#, result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -40,6 +40,14 @@ impl Command for GetWeek { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/date/get_weekday.rs b/crates/nu-command/src/dataframe/series/date/get_weekday.rs index 73ba75c84..611320cc3 100644 --- a/crates/nu-command/src/dataframe/series/date/get_weekday.rs +++ b/crates/nu-command/src/dataframe/series/date/get_weekday.rs @@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use polars::prelude::{DatetimeMethods, IntoSeries}; @@ -12,7 +12,7 @@ pub struct GetWeekDay; impl Command for GetWeekDay { fn name(&self) -> &str { - "dfr get-weekday" + "get-weekday" } fn usage(&self) -> &str { @@ -27,8 +27,8 @@ impl Command for GetWeekDay { vec![Example { description: "Returns weekday from a date", example: r#"let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC'); - let df = ([$dt $dt] | dfr to-df); - $df | dfr get-weekday"#, + let df = ([$dt $dt] | to-df); + $df | get-weekday"#, result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -40,6 +40,14 @@ impl Command for GetWeekDay { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/date/get_year.rs b/crates/nu-command/src/dataframe/series/date/get_year.rs index 481655632..2d3ba3222 100644 --- a/crates/nu-command/src/dataframe/series/date/get_year.rs +++ b/crates/nu-command/src/dataframe/series/date/get_year.rs @@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use polars::prelude::{DatetimeMethods, IntoSeries}; @@ -12,7 +12,7 @@ pub struct GetYear; impl Command for GetYear { fn name(&self) -> &str { - "dfr get-year" + "get-year" } fn usage(&self) -> &str { @@ -27,8 +27,8 @@ impl Command for GetYear { vec![Example { description: "Returns year from a date", example: r#"let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC'); - let df = ([$dt $dt] | dfr to-df); - $df | dfr get-year"#, + let df = ([$dt $dt] | to-df); + $df | get-year"#, result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -40,6 +40,14 @@ impl Command for GetYear { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/indexes/arg_sort.rs b/crates/nu-command/src/dataframe/series/indexes/arg_sort.rs index 879cc8e17..45c5e6376 100644 --- a/crates/nu-command/src/dataframe/series/indexes/arg_sort.rs +++ b/crates/nu-command/src/dataframe/series/indexes/arg_sort.rs @@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use polars::prelude::{IntoSeries, SortOptions}; @@ -12,7 +12,7 @@ pub struct ArgSort; impl Command for ArgSort { fn name(&self) -> &str { - "dfr arg-sort" + "arg-sort" } fn usage(&self) -> &str { @@ -30,7 +30,7 @@ impl Command for ArgSort { vec![ Example { description: "Returns indexes for a sorted series", - example: "[1 2 2 3 3] | dfr to-df | dfr arg-sort", + example: "[1 2 2 3 3] | to-df | arg-sort", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "arg_sort".to_string(), @@ -48,7 +48,7 @@ impl Command for ArgSort { }, Example { description: "Returns indexes for a sorted series", - example: "[1 2 2 3 3] | dfr to-df | dfr arg-sort -r", + example: "[1 2 2 3 3] | to-df | arg-sort -r", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "arg_sort".to_string(), @@ -67,6 +67,14 @@ impl Command for ArgSort { ] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/indexes/arg_true.rs b/crates/nu-command/src/dataframe/series/indexes/arg_true.rs index 9f641ec6d..de5456e70 100644 --- a/crates/nu-command/src/dataframe/series/indexes/arg_true.rs +++ b/crates/nu-command/src/dataframe/series/indexes/arg_true.rs @@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use polars::prelude::IntoSeries; @@ -12,7 +12,7 @@ pub struct ArgTrue; impl Command for ArgTrue { fn name(&self) -> &str { - "dfr arg-true" + "arg-true" } fn usage(&self) -> &str { @@ -26,7 +26,7 @@ impl Command for ArgTrue { fn examples(&self) -> Vec { vec![Example { description: "Returns indexes where values are true", - example: "[false true false] | dfr to-df | dfr arg-true", + example: "[false true false] | to-df | arg-true", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "arg_true".to_string(), @@ -38,6 +38,14 @@ impl Command for ArgTrue { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/indexes/arg_unique.rs b/crates/nu-command/src/dataframe/series/indexes/arg_unique.rs index 2821545f6..2b16745ac 100644 --- a/crates/nu-command/src/dataframe/series/indexes/arg_unique.rs +++ b/crates/nu-command/src/dataframe/series/indexes/arg_unique.rs @@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use polars::prelude::IntoSeries; @@ -12,7 +12,7 @@ pub struct ArgUnique; impl Command for ArgUnique { fn name(&self) -> &str { - "dfr arg-unique" + "arg-unique" } fn usage(&self) -> &str { @@ -26,7 +26,7 @@ impl Command for ArgUnique { fn examples(&self) -> Vec { vec![Example { description: "Returns indexes for unique values", - example: "[1 2 2 3 3] | dfr to-df | dfr arg-unique", + example: "[1 2 2 3 3] | to-df | arg-unique", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "arg_unique".to_string(), @@ -38,6 +38,14 @@ impl Command for ArgUnique { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/indexes/set_with_idx.rs b/crates/nu-command/src/dataframe/series/indexes/set_with_idx.rs index 17b98e95c..c9cb56df9 100644 --- a/crates/nu-command/src/dataframe/series/indexes/set_with_idx.rs +++ b/crates/nu-command/src/dataframe/series/indexes/set_with_idx.rs @@ -4,7 +4,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use polars::prelude::{ChunkSet, DataType, IntoSeries}; @@ -13,7 +13,7 @@ pub struct SetWithIndex; impl Command for SetWithIndex { fn name(&self) -> &str { - "dfr set-with-idx" + "set-with-idx" } fn usage(&self) -> &str { @@ -35,9 +35,9 @@ impl Command for SetWithIndex { fn examples(&self) -> Vec { vec![Example { description: "Set value in selected rows from series", - example: r#"let series = ([4 1 5 2 4 3] | dfr to-df); - let indices = ([0 2] | dfr to-df); - $series | dfr set-with-idx 6 -i $indices"#, + example: r#"let series = ([4 1 5 2 4 3] | to-df); + let indices = ([0 2] | to-df); + $series | set-with-idx 6 -i $indices"#, result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -56,6 +56,14 @@ impl Command for SetWithIndex { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/masks/is_duplicated.rs b/crates/nu-command/src/dataframe/series/masks/is_duplicated.rs index bf3b186e6..94ec37047 100644 --- a/crates/nu-command/src/dataframe/series/masks/is_duplicated.rs +++ b/crates/nu-command/src/dataframe/series/masks/is_duplicated.rs @@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use polars::prelude::IntoSeries; @@ -12,7 +12,7 @@ pub struct IsDuplicated; impl Command for IsDuplicated { fn name(&self) -> &str { - "dfr is-duplicated" + "is-duplicated" } fn usage(&self) -> &str { @@ -26,7 +26,7 @@ impl Command for IsDuplicated { fn examples(&self) -> Vec { vec![Example { description: "Create mask indicating duplicated values", - example: "[5 6 6 6 8 8 8] | dfr to-df | dfr is-duplicated", + example: "[5 6 6 6 8 8 8] | to-df | is-duplicated", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "is_duplicated".to_string(), @@ -46,6 +46,14 @@ impl Command for IsDuplicated { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/masks/is_in.rs b/crates/nu-command/src/dataframe/series/masks/is_in.rs index 747b470f4..a33285782 100644 --- a/crates/nu-command/src/dataframe/series/masks/is_in.rs +++ b/crates/nu-command/src/dataframe/series/masks/is_in.rs @@ -4,7 +4,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use polars::prelude::IntoSeries; @@ -13,7 +13,7 @@ pub struct IsIn; impl Command for IsIn { fn name(&self) -> &str { - "dfr is-in" + "is-in" } fn usage(&self) -> &str { @@ -29,8 +29,8 @@ impl Command for IsIn { fn examples(&self) -> Vec { vec![Example { description: "Checks if elements from a series are contained in right series", - example: r#"let other = ([1 3 6] | dfr to-df); - [5 6 6 6 8 8 8] | dfr to-df | dfr is-in $other"#, + example: r#"let other = ([1 3 6] | to-df); + [5 6 6 6 8 8 8] | to-df | is-in $other"#, result: Some( NuDataFrame::try_from_columns(vec![Column::new( "is_in".to_string(), @@ -50,6 +50,14 @@ impl Command for IsIn { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/masks/is_not_null.rs b/crates/nu-command/src/dataframe/series/masks/is_not_null.rs index a763df1a5..ccedd5da3 100644 --- a/crates/nu-command/src/dataframe/series/masks/is_not_null.rs +++ b/crates/nu-command/src/dataframe/series/masks/is_not_null.rs @@ -1,9 +1,8 @@ use super::super::super::values::{Column, NuDataFrame}; -use crate::dataframe::values::NuExpression; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use polars::prelude::IntoSeries; @@ -12,44 +11,45 @@ pub struct IsNotNull; impl Command for IsNotNull { fn name(&self) -> &str { - "dfr is-not-null" + "is-not-null" } fn usage(&self) -> &str { - "Creates mask where value is not null or creates a is-not-null expression" + "Creates mask where value is not null" } fn signature(&self) -> Signature { - Signature::build(self.name()).category(Category::Custom("dataframe or lazyframe".into())) + Signature::build(self.name()).category(Category::Custom("dataframe".into())) } fn examples(&self) -> Vec { - vec![ - Example { - description: "Create mask where values are not null", - example: r#"let s = ([5 6 0 8] | dfr to-df); + vec![Example { + description: "Create mask where values are not null", + example: r#"let s = ([5 6 0 8] | to-df); let res = ($s / $s); - $res | dfr is-not-null"#, - result: Some( - NuDataFrame::try_from_columns(vec![Column::new( - "is_not_null".to_string(), - vec![ - Value::test_bool(true), - Value::test_bool(true), - Value::test_bool(false), - Value::test_bool(true), - ], - )]) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }, - Example { - description: "Creates a is not null expression from a column", - example: "dfr col a | dfr is-not-null", - result: None, - }, - ] + $res | is-not-null"#, + result: Some( + NuDataFrame::try_from_columns(vec![Column::new( + "is_not_null".to_string(), + vec![ + Value::test_bool(true), + Value::test_bool(true), + Value::test_bool(false), + Value::test_bool(true), + ], + )]) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + }] + } + + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) } fn run( @@ -59,27 +59,8 @@ impl Command for IsNotNull { call: &Call, input: PipelineData, ) -> Result { - let value = input.into_value(call.head); - - if NuExpression::can_downcast(&value) { - let expr = NuExpression::try_from_value(value)?; - let expr: NuExpression = expr.into_polars().is_not_null().into(); - - Ok(PipelineData::Value( - NuExpression::into_value(expr, call.head), - None, - )) - } else if NuDataFrame::can_downcast(&value) { - let df = NuDataFrame::try_from_value(value)?; - command(engine_state, stack, call, df) - } else { - Err(ShellError::CantConvert( - "expression or query".into(), - value.get_type().to_string(), - value.span()?, - None, - )) - } + let df = NuDataFrame::try_from_pipeline(input, call.head)?; + command(engine_state, stack, call, df) } } diff --git a/crates/nu-command/src/dataframe/series/masks/is_null.rs b/crates/nu-command/src/dataframe/series/masks/is_null.rs index 6f9afbfad..e4dc171b5 100644 --- a/crates/nu-command/src/dataframe/series/masks/is_null.rs +++ b/crates/nu-command/src/dataframe/series/masks/is_null.rs @@ -1,9 +1,8 @@ use super::super::super::values::{Column, NuDataFrame}; -use crate::dataframe::values::NuExpression; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use polars::prelude::IntoSeries; @@ -12,44 +11,45 @@ pub struct IsNull; impl Command for IsNull { fn name(&self) -> &str { - "dfr is-null" + "is-null" } fn usage(&self) -> &str { - "Creates mask where value is null or creates a is-null expression" + "Creates mask where value is null" } fn signature(&self) -> Signature { - Signature::build(self.name()).category(Category::Custom("dataframe or expression".into())) + Signature::build(self.name()).category(Category::Custom("dataframe".into())) } fn examples(&self) -> Vec { - vec![ - Example { - description: "Create mask where values are null", - example: r#"let s = ([5 6 0 8] | dfr to-df); + vec![Example { + description: "Create mask where values are null", + example: r#"let s = ([5 6 0 8] | to-df); let res = ($s / $s); - $res | dfr is-null"#, - result: Some( - NuDataFrame::try_from_columns(vec![Column::new( - "is_null".to_string(), - vec![ - Value::test_bool(false), - Value::test_bool(false), - Value::test_bool(true), - Value::test_bool(false), - ], - )]) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }, - Example { - description: "Creates a is not null expression from a column", - example: "dfr col a | dfr is-null", - result: None, - }, - ] + $res | is-null"#, + result: Some( + NuDataFrame::try_from_columns(vec![Column::new( + "is_null".to_string(), + vec![ + Value::test_bool(false), + Value::test_bool(false), + Value::test_bool(true), + Value::test_bool(false), + ], + )]) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + }] + } + + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) } fn run( @@ -59,27 +59,8 @@ impl Command for IsNull { call: &Call, input: PipelineData, ) -> Result { - let value = input.into_value(call.head); - - if NuExpression::can_downcast(&value) { - let expr = NuExpression::try_from_value(value)?; - let expr: NuExpression = expr.into_polars().is_null().into(); - - Ok(PipelineData::Value( - NuExpression::into_value(expr, call.head), - None, - )) - } else if NuDataFrame::can_downcast(&value) { - let df = NuDataFrame::try_from_value(value)?; - command(engine_state, stack, call, df) - } else { - Err(ShellError::CantConvert( - "expression or query".into(), - value.get_type().to_string(), - value.span()?, - None, - )) - } + let df = NuDataFrame::try_from_pipeline(input, call.head)?; + command(engine_state, stack, call, df) } } diff --git a/crates/nu-command/src/dataframe/series/masks/is_unique.rs b/crates/nu-command/src/dataframe/series/masks/is_unique.rs index c0355c5c8..51fdc6211 100644 --- a/crates/nu-command/src/dataframe/series/masks/is_unique.rs +++ b/crates/nu-command/src/dataframe/series/masks/is_unique.rs @@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use polars::prelude::IntoSeries; @@ -12,7 +12,7 @@ pub struct IsUnique; impl Command for IsUnique { fn name(&self) -> &str { - "dfr is-unique" + "is-unique" } fn usage(&self) -> &str { @@ -26,7 +26,7 @@ impl Command for IsUnique { fn examples(&self) -> Vec { vec![Example { description: "Create mask indicating unique values", - example: "[5 6 6 6 8 8 8] | dfr to-df | dfr is-unique", + example: "[5 6 6 6 8 8 8] | to-df | is-unique", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "is_unique".to_string(), @@ -46,6 +46,14 @@ impl Command for IsUnique { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/masks/not.rs b/crates/nu-command/src/dataframe/series/masks/not.rs index d45b560ad..ac353ddf3 100644 --- a/crates/nu-command/src/dataframe/series/masks/not.rs +++ b/crates/nu-command/src/dataframe/series/masks/not.rs @@ -1,9 +1,8 @@ use super::super::super::values::{Column, NuDataFrame}; -use crate::dataframe::values::NuExpression; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use polars::prelude::IntoSeries; @@ -14,41 +13,42 @@ pub struct NotSeries; impl Command for NotSeries { fn name(&self) -> &str { - "dfr not" + "df-not" } fn usage(&self) -> &str { - "Inverts boolean mask or creates a not expression" + "Inverts boolean mask" } fn signature(&self) -> Signature { - Signature::build(self.name()).category(Category::Custom("dataframe or lazyframes".into())) + Signature::build(self.name()).category(Category::Custom("dataframe".into())) } fn examples(&self) -> Vec { - vec![ - Example { - description: "Inverts boolean mask", - example: "[true false true] | dfr to-df | dfr not", - result: Some( - NuDataFrame::try_from_columns(vec![Column::new( - "0".to_string(), - vec![ - Value::test_bool(false), - Value::test_bool(true), - Value::test_bool(false), - ], - )]) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }, - Example { - description: "Creates a not expression from a column", - example: "((dfr col a) > 2) | dfr not", - result: None, - }, - ] + vec![Example { + description: "Inverts boolean mask", + example: "[true false true] | to-df | df-not", + result: Some( + NuDataFrame::try_from_columns(vec![Column::new( + "0".to_string(), + vec![ + Value::test_bool(false), + Value::test_bool(true), + Value::test_bool(false), + ], + )]) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + }] + } + + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) } fn run( @@ -58,27 +58,8 @@ impl Command for NotSeries { call: &Call, input: PipelineData, ) -> Result { - let value = input.into_value(call.head); - - if NuExpression::can_downcast(&value) { - let expr = NuExpression::try_from_value(value)?; - let expr: NuExpression = expr.into_polars().is_null().into(); - - Ok(PipelineData::Value( - NuExpression::into_value(expr, call.head), - None, - )) - } else if NuDataFrame::can_downcast(&value) { - let df = NuDataFrame::try_from_value(value)?; - command(engine_state, stack, call, df) - } else { - Err(ShellError::CantConvert( - "expression or query".into(), - value.get_type().to_string(), - value.span()?, - None, - )) - } + let df = NuDataFrame::try_from_pipeline(input, call.head)?; + command(engine_state, stack, call, df) } } diff --git a/crates/nu-command/src/dataframe/series/masks/set.rs b/crates/nu-command/src/dataframe/series/masks/set.rs index b1d102887..11fa32e69 100644 --- a/crates/nu-command/src/dataframe/series/masks/set.rs +++ b/crates/nu-command/src/dataframe/series/masks/set.rs @@ -4,7 +4,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use polars::prelude::{ChunkSet, DataType, IntoSeries}; @@ -13,7 +13,7 @@ pub struct SetSeries; impl Command for SetSeries { fn name(&self) -> &str { - "dfr set" + "set" } fn usage(&self) -> &str { @@ -35,9 +35,9 @@ impl Command for SetSeries { fn examples(&self) -> Vec { vec![Example { description: "Shifts the values by a given period", - example: r#"let s = ([1 2 2 3 3] | dfr to-df | dfr shift 2); - let mask = ($s | dfr is-null); - $s | dfr set 0 --mask $mask"#, + example: r#"let s = ([1 2 2 3 3] | to-df | shift 2); + let mask = ($s | is-null); + $s | set 0 --mask $mask"#, result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -55,6 +55,14 @@ impl Command for SetSeries { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/n_null.rs b/crates/nu-command/src/dataframe/series/n_null.rs index 9bee66005..6a8b9d4e5 100644 --- a/crates/nu-command/src/dataframe/series/n_null.rs +++ b/crates/nu-command/src/dataframe/series/n_null.rs @@ -3,7 +3,7 @@ use super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; #[derive(Clone)] @@ -11,7 +11,7 @@ pub struct NNull; impl Command for NNull { fn name(&self) -> &str { - "dfr count-null" + "count-null" } fn usage(&self) -> &str { @@ -25,8 +25,8 @@ impl Command for NNull { fn examples(&self) -> Vec { vec![Example { description: "Counts null values", - example: r#"let s = ([1 1 0 0 3 3 4] | dfr to-df); - ($s / $s) | dfr count-null"#, + example: r#"let s = ([1 1 0 0 3 3 4] | to-df); + ($s / $s) | count-null"#, result: Some( NuDataFrame::try_from_columns(vec![Column::new( "count_null".to_string(), @@ -38,6 +38,14 @@ impl Command for NNull { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/n_unique.rs b/crates/nu-command/src/dataframe/series/n_unique.rs index bc642c91e..fb9a699c9 100644 --- a/crates/nu-command/src/dataframe/series/n_unique.rs +++ b/crates/nu-command/src/dataframe/series/n_unique.rs @@ -1,9 +1,8 @@ use super::super::values::{Column, NuDataFrame}; -use crate::dataframe::values::NuExpression; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; #[derive(Clone)] @@ -11,37 +10,38 @@ pub struct NUnique; impl Command for NUnique { fn name(&self) -> &str { - "dfr n-unique" + "n-unique" } fn usage(&self) -> &str { - "Counts unique values or creates a n-unique expression" + "Counts unique values" } fn signature(&self) -> Signature { - Signature::build(self.name()).category(Category::Custom("dataframe or expression".into())) + Signature::build(self.name()).category(Category::Custom("dataframe".into())) } fn examples(&self) -> Vec { - vec![ - Example { - description: "Counts unique values", - example: "[1 1 2 2 3 3 4] | dfr to-df | dfr n-unique", - result: Some( - NuDataFrame::try_from_columns(vec![Column::new( - "count_unique".to_string(), - vec![Value::test_int(4)], - )]) - .expect("simple df for test should not fail") - .into_value(Span::test_data()), - ), - }, - Example { - description: "Creates a is n-unique expression from a column", - example: "dfr col a | dfr n-unique", - result: None, - }, - ] + vec![Example { + description: "Counts unique values", + example: "[1 1 2 2 3 3 4] | to-df | n-unique", + result: Some( + NuDataFrame::try_from_columns(vec![Column::new( + "count_unique".to_string(), + vec![Value::test_int(4)], + )]) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + }] + } + + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) } fn run( @@ -51,27 +51,8 @@ impl Command for NUnique { call: &Call, input: PipelineData, ) -> Result { - let value = input.into_value(call.head); - - if NuExpression::can_downcast(&value) { - let expr = NuExpression::try_from_value(value)?; - let expr: NuExpression = expr.into_polars().n_unique().into(); - - Ok(PipelineData::Value( - NuExpression::into_value(expr, call.head), - None, - )) - } else if NuDataFrame::can_downcast(&value) { - let df = NuDataFrame::try_from_value(value)?; - command(engine_state, stack, call, df) - } else { - Err(ShellError::CantConvert( - "expression or query".into(), - value.get_type().to_string(), - value.span()?, - None, - )) - } + let df = NuDataFrame::try_from_pipeline(input, call.head)?; + command(engine_state, stack, call, df) } } diff --git a/crates/nu-command/src/dataframe/series/rolling.rs b/crates/nu-command/src/dataframe/series/rolling.rs index a6bda0e07..d250a308e 100644 --- a/crates/nu-command/src/dataframe/series/rolling.rs +++ b/crates/nu-command/src/dataframe/series/rolling.rs @@ -4,7 +4,8 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Type, + Value, }; use polars::prelude::{DataType, IntoSeries, RollingOptions}; @@ -47,7 +48,7 @@ pub struct Rolling; impl Command for Rolling { fn name(&self) -> &str { - "dfr rolling" + "rolling" } fn usage(&self) -> &str { @@ -65,7 +66,7 @@ impl Command for Rolling { vec![ Example { description: "Rolling sum for a series", - example: "[1 2 3 4 5] | dfr to-df | dfr rolling sum 2 | dfr drop-nulls", + example: "[1 2 3 4 5] | to-df | rolling sum 2 | drop-nulls", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0_rolling_sum".to_string(), @@ -82,7 +83,7 @@ impl Command for Rolling { }, Example { description: "Rolling max for a series", - example: "[1 2 3 4 5] | dfr to-df | dfr rolling max 2 | dfr drop-nulls", + example: "[1 2 3 4 5] | to-df | rolling max 2 | drop-nulls", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0_rolling_max".to_string(), @@ -100,6 +101,14 @@ impl Command for Rolling { ] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/shift.rs b/crates/nu-command/src/dataframe/series/shift.rs index 6c231a520..b544f9aad 100644 --- a/crates/nu-command/src/dataframe/series/shift.rs +++ b/crates/nu-command/src/dataframe/series/shift.rs @@ -6,7 +6,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; #[derive(Clone)] @@ -14,7 +14,7 @@ pub struct Shift; impl Command for Shift { fn name(&self) -> &str { - "dfr shift" + "shift" } fn usage(&self) -> &str { @@ -36,7 +36,7 @@ impl Command for Shift { fn examples(&self) -> Vec { vec![Example { description: "Shifts the values by a given period", - example: "[1 2 2 3 3] | dfr to-df | dfr shift 2 | dfr drop-nulls", + example: "[1 2 2 3 3] | to-df | shift 2 | drop-nulls", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -48,6 +48,14 @@ impl Command for Shift { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, @@ -60,16 +68,9 @@ impl Command for Shift { if NuLazyFrame::can_downcast(&value) { let df = NuLazyFrame::try_from_value(value)?; command_lazy(engine_state, stack, call, df) - } else if NuDataFrame::can_downcast(&value) { + } else { let df = NuDataFrame::try_from_value(value)?; command_eager(engine_state, stack, call, df) - } else { - Err(ShellError::CantConvert( - "expression or query".into(), - value.get_type().to_string(), - value.span()?, - None, - )) } } } diff --git a/crates/nu-command/src/dataframe/series/string/concatenate.rs b/crates/nu-command/src/dataframe/series/string/concatenate.rs index db65e66d8..6aa752ce0 100644 --- a/crates/nu-command/src/dataframe/series/string/concatenate.rs +++ b/crates/nu-command/src/dataframe/series/string/concatenate.rs @@ -4,7 +4,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use polars::prelude::IntoSeries; @@ -13,7 +13,7 @@ pub struct Concatenate; impl Command for Concatenate { fn name(&self) -> &str { - "dfr concatenate" + "concatenate" } fn usage(&self) -> &str { @@ -33,8 +33,8 @@ impl Command for Concatenate { fn examples(&self) -> Vec { vec![Example { description: "Concatenate string", - example: r#"let other = ([za xs cd] | dfr to-df); - [abc abc abc] | dfr to-df | dfr concatenate $other"#, + example: r#"let other = ([za xs cd] | to-df); + [abc abc abc] | to-df | concatenate $other"#, result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -50,6 +50,14 @@ impl Command for Concatenate { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/string/contains.rs b/crates/nu-command/src/dataframe/series/string/contains.rs index 9cdfc1957..68ffb338b 100644 --- a/crates/nu-command/src/dataframe/series/string/contains.rs +++ b/crates/nu-command/src/dataframe/series/string/contains.rs @@ -4,7 +4,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use polars::prelude::IntoSeries; @@ -13,7 +13,7 @@ pub struct Contains; impl Command for Contains { fn name(&self) -> &str { - "dfr contains" + "contains" } fn usage(&self) -> &str { @@ -33,7 +33,7 @@ impl Command for Contains { fn examples(&self) -> Vec { vec![Example { description: "Returns boolean indicating if pattern was found", - example: "[abc acb acb] | dfr to-df | dfr contains ab", + example: "[abc acb acb] | to-df | contains ab", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -49,6 +49,14 @@ impl Command for Contains { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/string/replace.rs b/crates/nu-command/src/dataframe/series/string/replace.rs index 4730dcfc5..65ca899c6 100644 --- a/crates/nu-command/src/dataframe/series/string/replace.rs +++ b/crates/nu-command/src/dataframe/series/string/replace.rs @@ -4,7 +4,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use polars::prelude::IntoSeries; @@ -13,7 +13,7 @@ pub struct Replace; impl Command for Replace { fn name(&self) -> &str { - "dfr replace" + "replace" } fn usage(&self) -> &str { @@ -40,7 +40,7 @@ impl Command for Replace { fn examples(&self) -> Vec { vec![Example { description: "Replaces string", - example: "[abc abc abc] | dfr to-df | dfr replace -p ab -r AB", + example: "[abc abc abc] | to-df | replace -p ab -r AB", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -56,6 +56,14 @@ impl Command for Replace { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/string/replace_all.rs b/crates/nu-command/src/dataframe/series/string/replace_all.rs index 18c47242c..e0cfbbfb4 100644 --- a/crates/nu-command/src/dataframe/series/string/replace_all.rs +++ b/crates/nu-command/src/dataframe/series/string/replace_all.rs @@ -4,7 +4,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use polars::prelude::IntoSeries; @@ -13,7 +13,7 @@ pub struct ReplaceAll; impl Command for ReplaceAll { fn name(&self) -> &str { - "dfr replace-all" + "replace-all" } fn usage(&self) -> &str { @@ -40,7 +40,7 @@ impl Command for ReplaceAll { fn examples(&self) -> Vec { vec![Example { description: "Replaces string", - example: "[abac abac abac] | dfr to-df | dfr replace-all -p a -r A", + example: "[abac abac abac] | to-df | replace-all -p a -r A", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -56,6 +56,14 @@ impl Command for ReplaceAll { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/string/str_lengths.rs b/crates/nu-command/src/dataframe/series/string/str_lengths.rs index aa828ce0f..b0be9679a 100644 --- a/crates/nu-command/src/dataframe/series/string/str_lengths.rs +++ b/crates/nu-command/src/dataframe/series/string/str_lengths.rs @@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use polars::prelude::IntoSeries; @@ -12,7 +12,7 @@ pub struct StrLengths; impl Command for StrLengths { fn name(&self) -> &str { - "dfr str-lengths" + "str-lengths" } fn usage(&self) -> &str { @@ -26,7 +26,7 @@ impl Command for StrLengths { fn examples(&self) -> Vec { vec![Example { description: "Returns string lengths", - example: "[a ab abc] | dfr to-df | dfr str-lengths", + example: "[a ab abc] | to-df | str-lengths", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -38,6 +38,14 @@ impl Command for StrLengths { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/string/str_slice.rs b/crates/nu-command/src/dataframe/series/string/str_slice.rs index c510b8c8f..dfb31e7ee 100644 --- a/crates/nu-command/src/dataframe/series/string/str_slice.rs +++ b/crates/nu-command/src/dataframe/series/string/str_slice.rs @@ -4,7 +4,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use polars::prelude::IntoSeries; @@ -13,7 +13,7 @@ pub struct StrSlice; impl Command for StrSlice { fn name(&self) -> &str { - "dfr str-slice" + "str-slice" } fn usage(&self) -> &str { @@ -30,7 +30,7 @@ impl Command for StrSlice { fn examples(&self) -> Vec { vec![Example { description: "Creates slices from the strings", - example: "[abcded abc321 abc123] | dfr to-df | dfr str-slice 1 -l 2", + example: "[abcded abc321 abc123] | to-df | str-slice 1 -l 2", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -46,6 +46,14 @@ impl Command for StrSlice { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/string/strftime.rs b/crates/nu-command/src/dataframe/series/string/strftime.rs index 5486d22af..772241460 100644 --- a/crates/nu-command/src/dataframe/series/string/strftime.rs +++ b/crates/nu-command/src/dataframe/series/string/strftime.rs @@ -4,7 +4,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use polars::prelude::IntoSeries; @@ -13,7 +13,7 @@ pub struct StrFTime; impl Command for StrFTime { fn name(&self) -> &str { - "dfr strftime" + "strftime" } fn usage(&self) -> &str { @@ -30,8 +30,8 @@ impl Command for StrFTime { vec![Example { description: "Formats date", example: r#"let dt = ('2020-08-04T16:39:18+00:00' | into datetime -z 'UTC'); - let df = ([$dt $dt] | dfr to-df); - $df | dfr strftime "%Y/%m/%d""#, + let df = ([$dt $dt] | to-df); + $df | strftime "%Y/%m/%d""#, result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -46,6 +46,14 @@ impl Command for StrFTime { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/string/to_lowercase.rs b/crates/nu-command/src/dataframe/series/string/to_lowercase.rs index a46fc872d..43c254cd2 100644 --- a/crates/nu-command/src/dataframe/series/string/to_lowercase.rs +++ b/crates/nu-command/src/dataframe/series/string/to_lowercase.rs @@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use polars::prelude::IntoSeries; @@ -12,7 +12,7 @@ pub struct ToLowerCase; impl Command for ToLowerCase { fn name(&self) -> &str { - "dfr to-lowercase" + "to-lowercase" } fn usage(&self) -> &str { @@ -26,7 +26,7 @@ impl Command for ToLowerCase { fn examples(&self) -> Vec { vec![Example { description: "Modifies strings to lowercase", - example: "[Abc aBc abC] | dfr to-df | dfr to-lowercase", + example: "[Abc aBc abC] | to-df | to-lowercase", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -42,6 +42,14 @@ impl Command for ToLowerCase { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/string/to_uppercase.rs b/crates/nu-command/src/dataframe/series/string/to_uppercase.rs index a7624a422..1b5c86a70 100644 --- a/crates/nu-command/src/dataframe/series/string/to_uppercase.rs +++ b/crates/nu-command/src/dataframe/series/string/to_uppercase.rs @@ -3,7 +3,7 @@ use super::super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; use polars::prelude::IntoSeries; @@ -12,7 +12,7 @@ pub struct ToUpperCase; impl Command for ToUpperCase { fn name(&self) -> &str { - "dfr to-uppercase" + "to-uppercase" } fn usage(&self) -> &str { @@ -26,7 +26,7 @@ impl Command for ToUpperCase { fn examples(&self) -> Vec { vec![Example { description: "Modifies strings to uppercase", - example: "[Abc aBc abC] | dfr to-df | dfr to-uppercase", + example: "[Abc aBc abC] | to-df | to-uppercase", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -42,6 +42,14 @@ impl Command for ToUpperCase { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/series/unique.rs b/crates/nu-command/src/dataframe/series/unique.rs index 4a2715ef9..1a7d5df1c 100644 --- a/crates/nu-command/src/dataframe/series/unique.rs +++ b/crates/nu-command/src/dataframe/series/unique.rs @@ -6,7 +6,7 @@ use nu_engine::CallExt; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value, + Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value, }; use polars::prelude::{IntoSeries, UniqueKeepStrategy}; @@ -15,11 +15,11 @@ pub struct Unique; impl Command for Unique { fn name(&self) -> &str { - "dfr unique" + "unique" } fn usage(&self) -> &str { - "Returns unique values from a series" + "Returns unique values from a dataframe" } fn signature(&self) -> Signature { @@ -40,14 +40,14 @@ impl Command for Unique { "Keep the same order as the original DataFrame (lazy df)", Some('k'), ) - .category(Category::Custom("dataframe or expression".into())) + .category(Category::Custom("dataframe or lazyframe".into())) } fn examples(&self) -> Vec { vec![ Example { description: "Returns unique values from a series", - example: "[2 2 2 2 2] | dfr to-df | dfr unique", + example: "[2 2 2 2 2] | to-df | unique", result: Some( NuDataFrame::try_from_columns(vec![Column::new( "0".to_string(), @@ -59,12 +59,20 @@ impl Command for Unique { }, Example { description: "Creates a is unique expression from a column", - example: "dfr col a | dfr unique", + example: "col a | unique", result: None, }, ] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, @@ -77,16 +85,9 @@ impl Command for Unique { if NuLazyFrame::can_downcast(&value) { let df = NuLazyFrame::try_from_value(value)?; command_lazy(engine_state, stack, call, df) - } else if NuDataFrame::can_downcast(&value) { + } else { let df = NuDataFrame::try_from_value(value)?; command_eager(engine_state, stack, call, df) - } else { - Err(ShellError::CantConvert( - "expression or query".into(), - value.get_type().to_string(), - value.span()?, - None, - )) } } } diff --git a/crates/nu-command/src/dataframe/series/value_counts.rs b/crates/nu-command/src/dataframe/series/value_counts.rs index 5ecbe7a12..a49c6a10c 100644 --- a/crates/nu-command/src/dataframe/series/value_counts.rs +++ b/crates/nu-command/src/dataframe/series/value_counts.rs @@ -3,7 +3,7 @@ use super::super::values::{Column, NuDataFrame}; use nu_protocol::{ ast::Call, engine::{Command, EngineState, Stack}, - Category, Example, PipelineData, ShellError, Signature, Span, Value, + Category, Example, PipelineData, ShellError, Signature, Span, Type, Value, }; #[derive(Clone)] @@ -11,7 +11,7 @@ pub struct ValueCount; impl Command for ValueCount { fn name(&self) -> &str { - "dfr value-counts" + "value-counts" } fn usage(&self) -> &str { @@ -25,7 +25,7 @@ impl Command for ValueCount { fn examples(&self) -> Vec { vec![Example { description: "Calculates value counts", - example: "[5 5 5 5 6 6] | dfr to-df | dfr value-counts", + example: "[5 5 5 5 6 6] | to-df | value-counts", result: Some( NuDataFrame::try_from_columns(vec![ Column::new( @@ -43,6 +43,14 @@ impl Command for ValueCount { }] } + fn input_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + + fn output_type(&self) -> Type { + Type::Custom("dataframe".into()) + } + fn run( &self, engine_state: &EngineState, diff --git a/crates/nu-command/src/dataframe/test_dataframe.rs b/crates/nu-command/src/dataframe/test_dataframe.rs index 3c22cc3dc..828cb4e85 100644 --- a/crates/nu-command/src/dataframe/test_dataframe.rs +++ b/crates/nu-command/src/dataframe/test_dataframe.rs @@ -6,6 +6,7 @@ use nu_protocol::{ }; use super::eager::ToDataFrame; +use super::expressions::ExprCol; use super::lazy::{LazyCollect, ToLazyFrame}; use crate::Let; @@ -26,6 +27,7 @@ pub fn test_dataframe(cmds: Vec>) { working_set.add_decl(Box::new(ToDataFrame)); working_set.add_decl(Box::new(ToLazyFrame)); working_set.add_decl(Box::new(LazyCollect)); + working_set.add_decl(Box::new(ExprCol)); // Adding the command that is being tested to the working set for cmd in cmds { diff --git a/crates/nu-command/src/dataframe/values/nu_expression/mod.rs b/crates/nu-command/src/dataframe/values/nu_expression/mod.rs index 8efa4eee3..4002eb308 100644 --- a/crates/nu-command/src/dataframe/values/nu_expression/mod.rs +++ b/crates/nu-command/src/dataframe/values/nu_expression/mod.rs @@ -174,7 +174,16 @@ pub fn expr_to_value(expr: &Expr, span: Span) -> Value { let cols = vec!["expr".to_string(), "value".to_string()]; match expr { - Expr::Not(_) => todo!(), + Expr::Not(expr) => { + let expr = expr_to_value(expr.as_ref(), span); + let cols = vec!["expr".into()]; + + Value::Record { + cols, + vals: vec![expr], + span, + } + } Expr::Alias(expr, alias) => { let expr = expr_to_value(expr.as_ref(), span); let alias = Value::String { @@ -182,7 +191,7 @@ pub fn expr_to_value(expr: &Expr, span: Span) -> Value { span, }; - let cols = vec!["expr".to_string(), "alias".to_string()]; + let cols = vec!["expr".into(), "alias".into()]; Value::Record { cols, @@ -192,7 +201,7 @@ pub fn expr_to_value(expr: &Expr, span: Span) -> Value { } Expr::Column(name) => { let expr_type = Value::String { - val: "column".into(), + val: "column".to_string(), span, }; let value = Value::String { @@ -222,7 +231,6 @@ pub fn expr_to_value(expr: &Expr, span: Span) -> Value { let vals = vec![expr_type, value]; Value::Record { cols, vals, span } } - Expr::DtypeColumn(_) => todo!(), Expr::Literal(literal) => { let expr_type = Value::String { val: "literal".into(), @@ -245,7 +253,7 @@ pub fn expr_to_value(expr: &Expr, span: Span) -> Value { span, }; - let cols = vec!["left".to_string(), "op".to_string(), "right".to_string()]; + let cols = vec!["left".into(), "op".into(), "right".into()]; Value::Record { cols, @@ -262,11 +270,7 @@ pub fn expr_to_value(expr: &Expr, span: Span) -> Value { let truthy = expr_to_value(truthy.as_ref(), span); let falsy = expr_to_value(falsy.as_ref(), span); - let cols = vec![ - "predicate".to_string(), - "truthy".to_string(), - "falsy".to_string(), - ]; + let cols = vec!["predicate".into(), "truthy".into(), "falsy".into()]; Value::Record { cols, @@ -289,7 +293,29 @@ pub fn expr_to_value(expr: &Expr, span: Span) -> Value { | AggExpr::AggGroups(expr) | AggExpr::Std(expr) | AggExpr::Var(expr) => expr_to_value(expr.as_ref(), span), - AggExpr::Quantile { .. } => todo!(), + AggExpr::Quantile { + expr, + quantile, + interpol, + } => { + let expr = expr_to_value(expr.as_ref(), span); + let quantile = Value::Float { + val: *quantile, + span, + }; + let interpol = Value::String { + val: format!("{:?}", interpol), + span, + }; + + let cols = vec!["expr".into(), "quantile".into(), "interpol".into()]; + + Value::Record { + cols, + vals: vec![expr, quantile, interpol], + span, + } + } }; let expr_type = Value::String { @@ -300,27 +326,371 @@ pub fn expr_to_value(expr: &Expr, span: Span) -> Value { let vals = vec![expr_type, value]; Value::Record { cols, vals, span } } - Expr::IsNotNull(_) => todo!(), - Expr::IsNull(_) => todo!(), - Expr::Cast { .. } => todo!(), - Expr::Sort { .. } => todo!(), - Expr::Take { .. } => todo!(), - Expr::SortBy { .. } => todo!(), - Expr::Function { .. } => todo!(), - Expr::Shift { .. } => todo!(), - Expr::Reverse(_) => todo!(), - Expr::Duplicated(_) => todo!(), - Expr::IsUnique(_) => todo!(), - Expr::Explode(_) => todo!(), - Expr::Filter { .. } => todo!(), - Expr::Window { .. } => todo!(), - Expr::Wildcard => todo!(), - Expr::Slice { .. } => todo!(), - Expr::Exclude(_, _) => todo!(), - Expr::KeepName(_) => todo!(), - Expr::RenameAlias { .. } => todo!(), - Expr::Count => todo!(), - Expr::Nth(_) => todo!(), - Expr::AnonymousFunction { .. } => todo!(), + Expr::IsNotNull(expr) => { + let expr = expr_to_value(expr.as_ref(), span); + let cols = vec!["expr".into()]; + + Value::Record { + cols, + vals: vec![expr], + span, + } + } + Expr::IsNull(expr) => { + let expr = expr_to_value(expr.as_ref(), span); + let cols = vec!["expr".into()]; + + Value::Record { + cols, + vals: vec![expr], + span, + } + } + Expr::Count => { + let expr = Value::String { + val: "count".into(), + span, + }; + let cols = vec!["expr".into()]; + + Value::Record { + cols, + vals: vec![expr], + span, + } + } + Expr::Wildcard => { + let expr = Value::String { + val: "wildcard".into(), + span, + }; + let cols = vec!["expr".into()]; + + Value::Record { + cols, + vals: vec![expr], + span, + } + } + Expr::Reverse(expr) => { + let expr = expr_to_value(expr.as_ref(), span); + let cols = vec!["expr".into()]; + + Value::Record { + cols, + vals: vec![expr], + span, + } + } + Expr::Duplicated(expr) => { + let expr = expr_to_value(expr.as_ref(), span); + let cols = vec!["expr".into()]; + + Value::Record { + cols, + vals: vec![expr], + span, + } + } + Expr::IsUnique(expr) => { + let expr = expr_to_value(expr.as_ref(), span); + let cols = vec!["expr".into()]; + + Value::Record { + cols, + vals: vec![expr], + span, + } + } + Expr::Explode(expr) => { + let expr = expr_to_value(expr.as_ref(), span); + let cols = vec!["expr".into()]; + + Value::Record { + cols, + vals: vec![expr], + span, + } + } + Expr::KeepName(expr) => { + let expr = expr_to_value(expr.as_ref(), span); + let cols = vec!["expr".into()]; + + Value::Record { + cols, + vals: vec![expr], + span, + } + } + Expr::Nth(i) => { + let expr = Value::int(*i, span); + let cols = vec!["expr".into()]; + + Value::Record { + cols, + vals: vec![expr], + span, + } + } + Expr::DtypeColumn(dtypes) => { + let vals = dtypes + .iter() + .map(|d| Value::String { + val: format!("{}", d), + span, + }) + .collect(); + + Value::List { vals, span } + } + Expr::Sort { expr, options } => { + let expr = expr_to_value(expr.as_ref(), span); + let options = Value::String { + val: format!("{:?}", options), + span, + }; + let cols = vec!["expr".into(), "options".into()]; + + Value::Record { + cols, + vals: vec![expr, options], + span, + } + } + Expr::Cast { + expr, + data_type, + strict, + } => { + let expr = expr_to_value(expr.as_ref(), span); + let dtype = Value::String { + val: format!("{:?}", data_type), + span, + }; + let strict = Value::Bool { val: *strict, span }; + + let cols = vec!["expr".into(), "dtype".into(), "strict".into()]; + + Value::Record { + cols, + vals: vec![expr, dtype, strict], + span, + } + } + Expr::Take { expr, idx } => { + let expr = expr_to_value(expr.as_ref(), span); + let idx = expr_to_value(idx.as_ref(), span); + + let cols = vec!["expr".into(), "idx".into()]; + + Value::Record { + cols, + vals: vec![expr, idx], + span, + } + } + Expr::SortBy { expr, by, reverse } => { + let expr = expr_to_value(expr.as_ref(), span); + let by: Vec = by.iter().map(|b| expr_to_value(b, span)).collect(); + let by = Value::List { vals: by, span }; + + let reverse: Vec = reverse + .iter() + .map(|r| Value::Bool { val: *r, span }) + .collect(); + let reverse = Value::List { + vals: reverse, + span, + }; + + let cols = vec!["expr".into(), "by".into(), "reverse".into()]; + + Value::Record { + cols, + vals: vec![expr, by, reverse], + span, + } + } + Expr::Shift { input, periods } => { + let expr = expr_to_value(input.as_ref(), span); + let periods = Value::Int { + val: *periods, + span, + }; + + let cols = vec!["expr".into(), "periods".into()]; + + Value::Record { + cols, + vals: vec![expr, periods], + span, + } + } + Expr::Filter { input, by } => { + let input = expr_to_value(input.as_ref(), span); + let by = expr_to_value(by.as_ref(), span); + + let cols = vec!["input".into(), "by".into()]; + + Value::Record { + cols, + vals: vec![input, by], + span, + } + } + Expr::Slice { + input, + offset, + length, + } => { + let input = expr_to_value(input.as_ref(), span); + let offset = expr_to_value(offset.as_ref(), span); + let length = expr_to_value(length.as_ref(), span); + + let cols = vec!["input".into(), "offset".into(), "length".into()]; + + Value::Record { + cols, + vals: vec![input, offset, length], + span, + } + } + Expr::Exclude(expr, excluded) => { + let expr = expr_to_value(expr.as_ref(), span); + let excluded = excluded + .iter() + .map(|e| Value::String { + val: format!("{:?}", e), + span, + }) + .collect(); + let excluded = Value::List { + vals: excluded, + span, + }; + + let cols = vec!["expr".into(), "excluded".into()]; + + Value::Record { + cols, + vals: vec![expr, excluded], + span, + } + } + Expr::RenameAlias { expr, function } => { + let expr = expr_to_value(expr.as_ref(), span); + let function = Value::String { + val: format!("{:?}", function), + span, + }; + + let cols = vec!["expr".into(), "function".into()]; + + Value::Record { + cols, + vals: vec![expr, function], + span, + } + } + Expr::AnonymousFunction { + input, + function, + output_type, + options, + } => { + let input: Vec = input.iter().map(|e| expr_to_value(e, span)).collect(); + let input = Value::List { vals: input, span }; + + let function = Value::String { + val: format!("{:?}", function), + span, + }; + let output_type = Value::String { + val: format!("{:?}", output_type), + span, + }; + let options = Value::String { + val: format!("{:?}", options), + span, + }; + + let cols = vec![ + "input".into(), + "function".into(), + "output_type".into(), + "options".into(), + ]; + + Value::Record { + cols, + vals: vec![input, function, output_type, options], + span, + } + } + Expr::Function { + input, + function, + options, + } => { + let input: Vec = input.iter().map(|e| expr_to_value(e, span)).collect(); + let input = Value::List { vals: input, span }; + + let function = Value::String { + val: format!("{:?}", function), + span, + }; + let options = Value::String { + val: format!("{:?}", options), + span, + }; + + let cols = vec!["input".into(), "function".into(), "options".into()]; + + Value::Record { + cols, + vals: vec![input, function, options], + span, + } + } + Expr::Window { + function, + partition_by, + order_by, + options, + } => { + let function = expr_to_value(function, span); + + let partition_by: Vec = partition_by + .iter() + .map(|e| expr_to_value(e, span)) + .collect(); + let partition_by = Value::List { + vals: partition_by, + span, + }; + + let order_by = order_by + .as_ref() + .map(|e| expr_to_value(e.as_ref(), span)) + .unwrap_or_else(|| Value::nothing(span)); + + let options = Value::String { + val: format!("{:?}", options), + span, + }; + + let cols = vec![ + "function".into(), + "partition_by".into(), + "order_by".into(), + "options".into(), + ]; + + Value::Record { + cols, + vals: vec![function, partition_by, order_by, options], + span, + } + } } } diff --git a/crates/nu-command/src/default_context.rs b/crates/nu-command/src/default_context.rs index 3662f7e25..7b11a62c6 100644 --- a/crates/nu-command/src/default_context.rs +++ b/crates/nu-command/src/default_context.rs @@ -400,9 +400,6 @@ pub fn create_default_context(cwd: impl AsRef) -> EngineState { KeepWhileDeprecated, }; - #[cfg(feature = "dataframe")] - bind_command!(DataframeDeprecated); - #[cfg(feature = "plugin")] bind_command!(Register); diff --git a/crates/nu-command/src/deprecated/dataframe.rs b/crates/nu-command/src/deprecated/dataframe.rs deleted file mode 100644 index 949a425ea..000000000 --- a/crates/nu-command/src/deprecated/dataframe.rs +++ /dev/null @@ -1,36 +0,0 @@ -use nu_protocol::{ - ast::Call, - engine::{Command, EngineState, Stack}, - Category, PipelineData, Signature, -}; - -#[derive(Clone)] -pub struct DataframeDeprecated; - -impl Command for DataframeDeprecated { - fn name(&self) -> &str { - "dataframe" - } - - fn signature(&self) -> Signature { - Signature::build(self.name()).category(Category::Deprecated) - } - - fn usage(&self) -> &str { - "Deprecated command" - } - - fn run( - &self, - _engine_state: &EngineState, - _stack: &mut Stack, - call: &Call, - _input: PipelineData, - ) -> Result { - Err(nu_protocol::ShellError::DeprecatedCommand( - self.name().to_string(), - "dfr".to_string(), - call.head, - )) - } -} diff --git a/crates/nu-command/src/deprecated/mod.rs b/crates/nu-command/src/deprecated/mod.rs index 5e3e8ca28..f4af1ca28 100644 --- a/crates/nu-command/src/deprecated/mod.rs +++ b/crates/nu-command/src/deprecated/mod.rs @@ -21,9 +21,3 @@ pub use str_decimal::StrDecimalDeprecated; pub use str_find_replace::StrFindReplaceDeprecated; pub use str_int::StrIntDeprecated; pub use unalias::UnaliasDeprecated; - -#[cfg(feature = "dataframe")] -mod dataframe; - -#[cfg(feature = "dataframe")] -pub use dataframe::DataframeDeprecated; diff --git a/crates/nu-parser/src/parse_keywords.rs b/crates/nu-parser/src/parse_keywords.rs index f0c250d32..59da17c26 100644 --- a/crates/nu-parser/src/parse_keywords.rs +++ b/crates/nu-parser/src/parse_keywords.rs @@ -21,7 +21,7 @@ use crate::{ parser::{ check_call, check_name, garbage, garbage_pipeline, parse, parse_block_expression, parse_internal_call, parse_multispan_value, parse_signature, parse_string, - parse_var_with_opt_type, trim_quotes, + parse_var_with_opt_type, trim_quotes, ParsedInternalCall, }, unescape_unquote_string, ParseError, }; @@ -127,13 +127,18 @@ pub fn parse_for( } Some(decl_id) => { working_set.enter_scope(); - let (call, mut err) = parse_internal_call( + let ParsedInternalCall { + call, + error: mut err, + output, + } = parse_internal_call( working_set, spans[0], &spans[1..], decl_id, expand_aliases_denylist, ); + working_set.exit_scope(); let call_span = span(spans); @@ -165,7 +170,7 @@ pub fn parse_for( Expression { expr: Expr::Call(call), span: call_span, - ty: Type::Any, + ty: output, custom_completion: None, }, err, @@ -296,13 +301,18 @@ pub fn parse_def( } Some(decl_id) => { working_set.enter_scope(); - let (call, mut err) = parse_internal_call( + let ParsedInternalCall { + call, + error: mut err, + output, + } = parse_internal_call( working_set, spans[0], &spans[1..], decl_id, expand_aliases_denylist, ); + working_set.exit_scope(); let call_span = span(spans); @@ -334,7 +344,7 @@ pub fn parse_def( Pipeline::from_vec(vec![Expression { expr: Expr::Call(call), span: call_span, - ty: Type::Any, + ty: output, custom_completion: None, }]), err, @@ -439,7 +449,9 @@ pub fn parse_extern( } Some(decl_id) => { working_set.enter_scope(); - let (call, err) = parse_internal_call( + let ParsedInternalCall { + call, error: err, .. + } = parse_internal_call( working_set, spans[0], &spans[1..], @@ -521,7 +533,7 @@ pub fn parse_alias( } if let Some(decl_id) = working_set.find_decl(b"alias", &Type::Any) { - let (call, _) = parse_internal_call( + let ParsedInternalCall { call, output, .. } = parse_internal_call( working_set, spans[0], &spans[1..], @@ -534,7 +546,7 @@ pub fn parse_alias( Pipeline::from_vec(vec![Expression { expr: Expr::Call(call), span: span(spans), - ty: Type::Any, + ty: output, custom_completion: None, }]), None, @@ -1243,7 +1255,11 @@ pub fn parse_use( let (call, call_span, use_decl_id) = match working_set.find_decl(b"use", &Type::Any) { Some(decl_id) => { - let (call, mut err) = parse_internal_call( + let ParsedInternalCall { + call, + error: mut err, + output, + } = parse_internal_call( working_set, spans[0], &spans[1..], @@ -1260,7 +1276,7 @@ pub fn parse_use( Pipeline::from_vec(vec![Expression { expr: Expr::Call(call), span: call_span, - ty: Type::Any, + ty: output, custom_completion: None, }]), err, @@ -1476,7 +1492,11 @@ pub fn parse_hide( let (call, call_span, hide_decl_id) = match working_set.find_decl(b"hide", &Type::Any) { Some(decl_id) => { - let (call, mut err) = parse_internal_call( + let ParsedInternalCall { + call, + error: mut err, + output, + } = parse_internal_call( working_set, spans[0], &spans[1..], @@ -1493,7 +1513,7 @@ pub fn parse_hide( Pipeline::from_vec(vec![Expression { expr: Expr::Call(call), span: call_span, - ty: Type::Any, + ty: output, custom_completion: None, }]), err, @@ -1701,7 +1721,11 @@ pub fn parse_overlay( // TODO: Abstract this code blob, it's repeated all over the place: let call = match working_set.find_decl(b"overlay list", &Type::Any) { Some(decl_id) => { - let (call, mut err) = parse_internal_call( + let ParsedInternalCall { + call, + error: mut err, + output, + } = parse_internal_call( working_set, span(&spans[..2]), if spans.len() > 2 { &spans[2..] } else { &[] }, @@ -1718,7 +1742,7 @@ pub fn parse_overlay( Pipeline::from_vec(vec![Expression { expr: Expr::Call(call), span: call_span, - ty: Type::Any, + ty: output, custom_completion: None, }]), err, @@ -1760,7 +1784,11 @@ pub fn parse_overlay( let call = match working_set.find_decl(b"overlay", &Type::Any) { Some(decl_id) => { - let (call, mut err) = parse_internal_call( + let ParsedInternalCall { + call, + error: mut err, + output, + } = parse_internal_call( working_set, spans[0], &spans[1..], @@ -1777,7 +1805,7 @@ pub fn parse_overlay( Pipeline::from_vec(vec![Expression { expr: Expr::Call(call), span: call_span, - ty: Type::Any, + ty: output, custom_completion: None, }]), err, @@ -1825,7 +1853,11 @@ pub fn parse_overlay_new( let (call, call_span) = match working_set.find_decl(b"overlay new", &Type::Any) { Some(decl_id) => { - let (call, mut err) = parse_internal_call( + let ParsedInternalCall { + call, + error: mut err, + output, + } = parse_internal_call( working_set, span(&spans[0..2]), &spans[2..], @@ -1842,7 +1874,7 @@ pub fn parse_overlay_new( Pipeline::from_vec(vec![Expression { expr: Expr::Call(call), span: call_span, - ty: Type::Any, + ty: output, custom_completion: None, }]), err, @@ -1916,7 +1948,11 @@ pub fn parse_overlay_add( // TODO: Allow full import pattern as argument (requires custom naming of module/overlay) let (call, call_span) = match working_set.find_decl(b"overlay add", &Type::Any) { Some(decl_id) => { - let (call, mut err) = parse_internal_call( + let ParsedInternalCall { + call, + error: mut err, + output, + } = parse_internal_call( working_set, span(&spans[0..2]), &spans[2..], @@ -1933,7 +1969,7 @@ pub fn parse_overlay_add( Pipeline::from_vec(vec![Expression { expr: Expr::Call(call), span: call_span, - ty: Type::Any, + ty: output, custom_completion: None, }]), err, @@ -2103,7 +2139,11 @@ pub fn parse_overlay_remove( let call = match working_set.find_decl(b"overlay remove", &Type::Any) { Some(decl_id) => { - let (call, mut err) = parse_internal_call( + let ParsedInternalCall { + call, + error: mut err, + output, + } = parse_internal_call( working_set, span(&spans[0..2]), &spans[2..], @@ -2120,7 +2160,7 @@ pub fn parse_overlay_remove( Pipeline::from_vec(vec![Expression { expr: Expr::Call(call), span: call_span, - ty: Type::Any, + ty: output, custom_completion: None, }]), err, @@ -2247,7 +2287,6 @@ pub fn parse_let( error = error.or(err); let var_id = lvalue.as_var(); - let rhs_type = rvalue.ty.clone(); if let Some(var_id) = var_id { @@ -2277,7 +2316,11 @@ pub fn parse_let( } } } - let (call, err) = parse_internal_call( + let ParsedInternalCall { + call, + error: err, + output, + } = parse_internal_call( working_set, spans[0], &spans[1..], @@ -2290,7 +2333,7 @@ pub fn parse_let( expressions: vec![Expression { expr: Expr::Call(call), span: nu_protocol::span(spans), - ty: Type::Any, + ty: output, custom_completion: None, }], }, @@ -2320,7 +2363,11 @@ pub fn parse_source( let cwd = working_set.get_cwd(); // Is this the right call to be using here? // Some of the others (`parse_let`) use it, some of them (`parse_hide`) don't. - let (call, err) = parse_internal_call( + let ParsedInternalCall { + call, + error: err, + output, + } = parse_internal_call( working_set, spans[0], &spans[1..], @@ -2334,7 +2381,7 @@ pub fn parse_source( Pipeline::from_vec(vec![Expression { expr: Expr::Call(call), span: span(spans), - ty: Type::Any, + ty: output, custom_completion: None, }]), error, @@ -2459,7 +2506,11 @@ pub fn parse_register( ) } Some(decl_id) => { - let (call, mut err) = parse_internal_call( + let ParsedInternalCall { + call, + error: mut err, + output, + } = parse_internal_call( working_set, spans[0], &spans[1..], @@ -2476,7 +2527,7 @@ pub fn parse_register( Pipeline::from_vec(vec![Expression { expr: Expr::Call(call), span: call_span, - ty: Type::Any, + ty: output, custom_completion: None, }]), err, diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index af010b46b..0178930d7 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -724,13 +724,19 @@ pub fn parse_multispan_value( } } +pub struct ParsedInternalCall { + pub call: Box, + pub output: Type, + pub error: Option, +} + pub fn parse_internal_call( working_set: &mut StateWorkingSet, command_span: Span, spans: &[Span], decl_id: usize, expand_aliases_denylist: &[usize], -) -> (Box, Option) { +) -> ParsedInternalCall { trace!("parsing: internal call (decl id: {})", decl_id); let mut error = None; @@ -742,7 +748,8 @@ pub fn parse_internal_call( let decl = working_set.get_decl(decl_id); let signature = decl.signature(); let output = decl.output_type(); - working_set.found_outputs.push(output); + + working_set.type_scope.add_type(output.clone()); if signature.creates_scope { working_set.enter_scope(); @@ -925,8 +932,11 @@ pub fn parse_internal_call( working_set.exit_scope(); } - // FIXME: output type unknown - (Box::new(call), error) + ParsedInternalCall { + call: Box::new(call), + output, + error, + } } pub fn parse_call( @@ -1012,7 +1022,7 @@ pub fn parse_call( pos += 1; } - let input = working_set.found_outputs.last().unwrap_or(&Type::Any); + let input = working_set.type_scope.get_previous(); let mut maybe_decl_id = working_set.find_decl(&name, input); while maybe_decl_id.is_none() { @@ -1060,21 +1070,22 @@ pub fn parse_call( trace!("parsing: internal call"); // parse internal command - let (call, err) = parse_internal_call( + let parsed_call = parse_internal_call( working_set, span(&spans[cmd_start..pos]), &spans[pos..], decl_id, expand_aliases_denylist, ); + ( Expression { - expr: Expr::Call(call), + expr: Expr::Call(parsed_call.call), span: span(spans), - ty: Type::Any, // FIXME: calls should have known output types + ty: parsed_call.output, custom_completion: None, }, - err, + parsed_call.error, ) } else { // We might be parsing left-unbounded range ("..10") @@ -1853,8 +1864,14 @@ pub fn parse_full_cell_path( let (output, err) = lite_parse(&output); error = error.or(err); + // Creating a Type scope to parse the new block. This will keep track of + // the previous input type found in that block let (output, err) = parse_block(working_set, &output, true, expand_aliases_denylist, true); + working_set + .type_scope + .add_type(working_set.type_scope.get_last_output()); + error = error.or(err); let block_id = working_set.add_block(output); @@ -1864,7 +1881,7 @@ pub fn parse_full_cell_path( Expression { expr: Expr::Subexpression(block_id), span: head_span, - ty: Type::Any, // FIXME + ty: working_set.type_scope.get_last_output(), custom_completion: None, }, true, @@ -1929,8 +1946,8 @@ pub fn parse_full_cell_path( if !tail.is_empty() { ( Expression { + ty: head.ty.clone(), // FIXME. How to access the last type of tail? expr: Expr::FullCellPath(Box::new(FullCellPath { head, tail })), - ty: Type::Any, span: full_cell_span, custom_completion: None, }, @@ -4581,6 +4598,9 @@ pub fn parse_variable( if is_variable(bytes) { if let Some(var_id) = working_set.find_variable(bytes) { + let input = working_set.get_variable(var_id).ty.clone(); + working_set.type_scope.add_type(input); + (Some(var_id), None) } else { (None, None) @@ -4612,19 +4632,20 @@ pub fn parse_builtin_commands( b"source" => parse_source(working_set, &lite_command.parts, expand_aliases_denylist), b"export" => { if let Some(decl_id) = working_set.find_decl(b"alias", &Type::Any) { - let (call, _) = parse_internal_call( + let parsed_call = parse_internal_call( working_set, lite_command.parts[0], &lite_command.parts[1..], decl_id, expand_aliases_denylist, ); - if call.has_flag("help") { + + if parsed_call.call.has_flag("help") { ( Pipeline::from_vec(vec![Expression { - expr: Expr::Call(call), + expr: Expr::Call(parsed_call.call), span: span(&lite_command.parts), - ty: Type::Any, + ty: parsed_call.output, custom_completion: None, }]), None, @@ -4759,6 +4780,7 @@ pub fn parse_block( if scoped { working_set.enter_scope(); } + working_set.type_scope.enter_scope(); let mut error = None; @@ -4789,6 +4811,8 @@ pub fn parse_block( let (expr, err) = parse_expression(working_set, &command.parts, expand_aliases_denylist); + working_set.type_scope.add_type(expr.ty.clone()); + if error.is_none() { error = err; } @@ -4872,6 +4896,7 @@ pub fn parse_block( if scoped { working_set.exit_scope(); } + working_set.type_scope.exit_scope(); (block, error) } diff --git a/crates/nu-parser/src/type_check.rs b/crates/nu-parser/src/type_check.rs index 9b2bf3696..f7365e29c 100644 --- a/crates/nu-parser/src/type_check.rs +++ b/crates/nu-parser/src/type_check.rs @@ -35,6 +35,9 @@ pub fn math_result_type( (Type::Duration, Type::Duration) => (Type::Duration, None), (Type::Filesize, Type::Filesize) => (Type::Filesize, None), + (Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None), + (Type::Custom(a), _) => (Type::Custom(a.to_string()), None), + (Type::Any, _) => (Type::Any, None), (_, Type::Any) => (Type::Any, None), (Type::Int, _) => { @@ -74,6 +77,9 @@ pub fn math_result_type( (Type::Duration, Type::Duration) => (Type::Duration, None), (Type::Filesize, Type::Filesize) => (Type::Filesize, None), + (Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None), + (Type::Custom(a), _) => (Type::Custom(a.to_string()), None), + (Type::Any, _) => (Type::Any, None), (_, Type::Any) => (Type::Any, None), _ => { @@ -101,6 +107,9 @@ pub fn math_result_type( (Type::Duration, Type::Int) => (Type::Filesize, None), (Type::Int, Type::Duration) => (Type::Filesize, None), + (Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None), + (Type::Custom(a), _) => (Type::Custom(a.to_string()), None), + (Type::Any, _) => (Type::Any, None), (_, Type::Any) => (Type::Any, None), _ => { @@ -123,6 +132,9 @@ pub fn math_result_type( (Type::Int, Type::Float) => (Type::Float, None), (Type::Float, Type::Float) => (Type::Float, None), + (Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None), + (Type::Custom(a), _) => (Type::Custom(a.to_string()), None), + (Type::Any, _) => (Type::Any, None), (_, Type::Any) => (Type::Any, None), _ => { @@ -150,6 +162,9 @@ pub fn math_result_type( (Type::Filesize, Type::Int) => (Type::Filesize, None), (Type::Duration, Type::Int) => (Type::Duration, None), + (Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None), + (Type::Custom(a), _) => (Type::Custom(a.to_string()), None), + (Type::Any, _) => (Type::Any, None), (_, Type::Any) => (Type::Any, None), _ => { @@ -169,6 +184,9 @@ pub fn math_result_type( Operator::And | Operator::Or => match (&lhs.ty, &rhs.ty) { (Type::Bool, Type::Bool) => (Type::Bool, None), + (Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None), + (Type::Custom(a), _) => (Type::Custom(a.to_string()), None), + (Type::Any, _) => (Type::Any, None), (_, Type::Any) => (Type::Any, None), _ => { @@ -193,6 +211,9 @@ pub fn math_result_type( (Type::Duration, Type::Duration) => (Type::Bool, None), (Type::Filesize, Type::Filesize) => (Type::Bool, None), + (Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None), + (Type::Custom(a), _) => (Type::Custom(a.to_string()), None), + (Type::Any, _) => (Type::Bool, None), (_, Type::Any) => (Type::Bool, None), _ => { @@ -217,6 +238,9 @@ pub fn math_result_type( (Type::Duration, Type::Duration) => (Type::Bool, None), (Type::Filesize, Type::Filesize) => (Type::Bool, None), + (Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None), + (Type::Custom(a), _) => (Type::Custom(a.to_string()), None), + (Type::Any, _) => (Type::Bool, None), (_, Type::Any) => (Type::Bool, None), _ => { @@ -241,6 +265,9 @@ pub fn math_result_type( (Type::Duration, Type::Duration) => (Type::Bool, None), (Type::Filesize, Type::Filesize) => (Type::Bool, None), + (Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None), + (Type::Custom(a), _) => (Type::Custom(a.to_string()), None), + (Type::Any, _) => (Type::Bool, None), (_, Type::Any) => (Type::Bool, None), _ => { @@ -265,6 +292,9 @@ pub fn math_result_type( (Type::Duration, Type::Duration) => (Type::Bool, None), (Type::Filesize, Type::Filesize) => (Type::Bool, None), + (Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None), + (Type::Custom(a), _) => (Type::Custom(a.to_string()), None), + (Type::Any, _) => (Type::Bool, None), (_, Type::Any) => (Type::Bool, None), _ => { @@ -281,12 +311,26 @@ pub fn math_result_type( ) } }, - Operator::Equal => (Type::Bool, None), - Operator::NotEqual => (Type::Bool, None), + Operator::Equal => match (&lhs.ty, &rhs.ty) { + (Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None), + (Type::Custom(a), _) => (Type::Custom(a.to_string()), None), + + _ => (Type::Bool, None), + }, + Operator::NotEqual => match (&lhs.ty, &rhs.ty) { + (Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None), + (Type::Custom(a), _) => (Type::Custom(a.to_string()), None), + + _ => (Type::Bool, None), + }, Operator::RegexMatch => match (&lhs.ty, &rhs.ty) { (Type::String, Type::String) => (Type::Bool, None), (Type::Any, _) => (Type::Bool, None), (_, Type::Any) => (Type::Bool, None), + + (Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None), + (Type::Custom(a), _) => (Type::Custom(a.to_string()), None), + _ => { *op = Expression::garbage(op.span); ( @@ -305,6 +349,10 @@ pub fn math_result_type( (Type::String, Type::String) => (Type::Bool, None), (Type::Any, _) => (Type::Bool, None), (_, Type::Any) => (Type::Bool, None), + + (Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None), + (Type::Custom(a), _) => (Type::Custom(a.to_string()), None), + _ => { *op = Expression::garbage(op.span); ( @@ -323,6 +371,10 @@ pub fn math_result_type( (Type::String, Type::String) => (Type::Bool, None), (Type::Any, _) => (Type::Bool, None), (_, Type::Any) => (Type::Bool, None), + + (Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None), + (Type::Custom(a), _) => (Type::Custom(a.to_string()), None), + _ => { *op = Expression::garbage(op.span); ( @@ -341,6 +393,10 @@ pub fn math_result_type( (Type::String, Type::String) => (Type::Bool, None), (Type::Any, _) => (Type::Bool, None), (_, Type::Any) => (Type::Bool, None), + + (Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None), + (Type::Custom(a), _) => (Type::Custom(a.to_string()), None), + _ => { *op = Expression::garbage(op.span); ( @@ -361,6 +417,9 @@ pub fn math_result_type( (Type::String, Type::String) => (Type::Bool, None), (Type::String, Type::Record(_)) => (Type::Bool, None), + (Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None), + (Type::Custom(a), _) => (Type::Custom(a.to_string()), None), + (Type::Any, _) => (Type::Bool, None), (_, Type::Any) => (Type::Bool, None), _ => { @@ -383,6 +442,9 @@ pub fn math_result_type( (Type::String, Type::String) => (Type::Bool, None), (Type::String, Type::Record(_)) => (Type::Bool, None), + (Type::Custom(a), Type::Custom(b)) if a == b => (Type::Custom(a.to_string()), None), + (Type::Custom(a), _) => (Type::Custom(a.to_string()), None), + (Type::Any, _) => (Type::Bool, None), (_, Type::Any) => (Type::Bool, None), _ => { diff --git a/crates/nu-parser/tests/test_parser.rs b/crates/nu-parser/tests/test_parser.rs index 408e0b30b..7e68f5cec 100644 --- a/crates/nu-parser/tests/test_parser.rs +++ b/crates/nu-parser/tests/test_parser.rs @@ -666,7 +666,7 @@ mod range { #[cfg(test)] mod input_types { use super::*; - use nu_protocol::{Category, Type}; + use nu_protocol::{ast::Argument, Category, Type}; #[derive(Clone)] pub struct LsTest; @@ -696,9 +696,9 @@ mod input_types { } #[derive(Clone)] - pub struct GroupByList; + pub struct GroupBy; - impl Command for GroupByList { + impl Command for GroupBy { fn name(&self) -> &str { "group-by" } @@ -830,16 +830,118 @@ mod input_types { } } + #[derive(Clone)] + pub struct AggMin; + + impl Command for AggMin { + fn name(&self) -> &str { + "min" + } + + fn usage(&self) -> &str { + "Mock custom min command" + } + + fn signature(&self) -> nu_protocol::Signature { + Signature::build(self.name()).category(Category::Custom("custom".into())) + } + + fn run( + &self, + _engine_state: &EngineState, + _stack: &mut Stack, + _call: &nu_protocol::ast::Call, + _input: nu_protocol::PipelineData, + ) -> Result { + todo!() + } + } + + #[derive(Clone)] + pub struct WithColumn; + + impl Command for WithColumn { + fn name(&self) -> &str { + "with-column" + } + + fn usage(&self) -> &str { + "Mock custom with-column command" + } + + fn signature(&self) -> nu_protocol::Signature { + Signature::build(self.name()) + .rest("operation", SyntaxShape::Any, "operation") + .category(Category::Custom("custom".into())) + } + + fn input_type(&self) -> nu_protocol::Type { + Type::Custom("custom".into()) + } + + fn output_type(&self) -> nu_protocol::Type { + Type::Custom("custom".into()) + } + + fn run( + &self, + _engine_state: &EngineState, + _stack: &mut Stack, + _call: &nu_protocol::ast::Call, + _input: nu_protocol::PipelineData, + ) -> Result { + todo!() + } + } + + #[derive(Clone)] + pub struct Collect; + + impl Command for Collect { + fn name(&self) -> &str { + "collect" + } + + fn usage(&self) -> &str { + "Mock custom collect command" + } + + fn signature(&self) -> nu_protocol::Signature { + Signature::build(self.name()).category(Category::Custom("custom".into())) + } + + fn input_type(&self) -> nu_protocol::Type { + Type::Custom("custom".into()) + } + + fn output_type(&self) -> nu_protocol::Type { + Type::Custom("custom".into()) + } + + fn run( + &self, + _engine_state: &EngineState, + _stack: &mut Stack, + _call: &nu_protocol::ast::Call, + _input: nu_protocol::PipelineData, + ) -> Result { + todo!() + } + } + fn add_declations(engine_state: &mut EngineState) { let delta = { let mut working_set = StateWorkingSet::new(&engine_state); working_set.add_decl(Box::new(Let)); working_set.add_decl(Box::new(AggCustom)); working_set.add_decl(Box::new(GroupByCustom)); - working_set.add_decl(Box::new(GroupByList)); + working_set.add_decl(Box::new(GroupBy)); working_set.add_decl(Box::new(LsTest)); working_set.add_decl(Box::new(ToCustom)); working_set.add_decl(Box::new(Let)); + working_set.add_decl(Box::new(AggMin)); + working_set.add_decl(Box::new(Collect)); + working_set.add_decl(Box::new(WithColumn)); working_set.render() }; @@ -917,6 +1019,64 @@ mod input_types { } } + #[test] + fn stored_variable_operation_test() { + let mut engine_state = EngineState::new(); + add_declations(&mut engine_state); + + let mut working_set = StateWorkingSet::new(&engine_state); + let input = r#"let a = (ls | to-custom | group-by name other); ($a + $a) | agg sum"#; + + let (block, err) = parse(&mut working_set, None, input.as_bytes(), true, &[]); + + assert!(err.is_none()); + assert!(block.len() == 2); + + let expressions = &block[1]; + match &expressions[1].expr { + Expr::Call(call) => { + let expected_id = working_set + .find_decl(b"agg", &Type::Custom("custom".into())) + .unwrap(); + assert_eq!(call.decl_id, expected_id) + } + _ => panic!("Expected expression Call not found"), + } + } + + #[test] + fn multiple_stored_variable_test() { + let mut engine_state = EngineState::new(); + add_declations(&mut engine_state); + + let mut working_set = StateWorkingSet::new(&engine_state); + let input = r#" + let a = (ls | to-custom | group-by name other); [1 2 3] | to-custom; [1 2 3] | to-custom"#; + + let (block, err) = parse(&mut working_set, None, input.as_bytes(), true, &[]); + + assert!(err.is_none()); + assert!(block.len() == 3); + + let expressions = &block[1]; + match &expressions[1].expr { + Expr::Call(call) => { + let expected_id = working_set.find_decl(b"to-custom", &Type::Any).unwrap(); + assert_eq!(call.decl_id, expected_id) + } + _ => panic!("Expected expression Call not found"), + } + + let expressions = &block[2]; + match &expressions[1].expr { + Expr::Call(call) => { + let expected_id = working_set.find_decl(b"to-custom", &Type::Any).unwrap(); + assert_eq!(call.decl_id, expected_id) + } + _ => panic!("Expected expression Call not found"), + } + } + #[test] fn call_non_custom_types_test() { let mut engine_state = EngineState::new(); @@ -949,4 +1109,89 @@ mod input_types { _ => panic!("Expected expression Call not found"), } } + + #[test] + fn nested_operations_test() { + let mut engine_state = EngineState::new(); + add_declations(&mut engine_state); + + let (block, delta) = { + let mut working_set = StateWorkingSet::new(&engine_state); + let input = r#"ls | to-custom | group-by name other | agg ("b" | min)"#; + let (block, _) = parse(&mut working_set, None, input.as_bytes(), true, &[]); + + (block, working_set.render()) + }; + + let cwd = std::env::current_dir().expect("Could not get current working directory."); + let _ = engine_state.merge_delta(delta, None, &cwd); + + let expressions = &block[0]; + match &expressions[3].expr { + Expr::Call(call) => { + let arg = &call.arguments[0]; + match arg { + Argument::Positional(a) => match &a.expr { + Expr::FullCellPath(path) => match &path.head.expr { + Expr::Subexpression(id) => { + let block = engine_state.get_block(*id); + + let expressions = &block[0]; + assert!(expressions.len() == 2); + + match &expressions[1].expr { + Expr::Call(call) => { + let working_set = StateWorkingSet::new(&engine_state); + let expected_id = + working_set.find_decl(b"min", &Type::Any).unwrap(); + assert_eq!(call.decl_id, expected_id) + } + _ => panic!("Expected expression Call not found"), + } + } + _ => panic!("Expected Subexpression not found"), + }, + _ => panic!("Expected FullCellPath not found"), + }, + _ => panic!("Expected Argument Positional not found"), + } + } + _ => panic!("Expected expression Call not found"), + } + } + + #[test] + fn call_with_list_test() { + let mut engine_state = EngineState::new(); + add_declations(&mut engine_state); + + let mut working_set = StateWorkingSet::new(&engine_state); + let input = r#"[[a b]; [1 2] [3 4]] | to-custom | with-column [ ("a" | min) ("b" | min) ] | collect"#; + + let (block, err) = parse(&mut working_set, None, input.as_bytes(), true, &[]); + + assert!(err.is_none()); + assert!(block.len() == 1); + + let expressions = &block[0]; + match &expressions[2].expr { + Expr::Call(call) => { + let expected_id = working_set + .find_decl(b"with-column", &Type::Custom("custom".into())) + .unwrap(); + assert_eq!(call.decl_id, expected_id) + } + _ => panic!("Expected expression Call not found"), + } + + match &expressions[3].expr { + Expr::Call(call) => { + let expected_id = working_set + .find_decl(b"collect", &Type::Custom("custom".into())) + .unwrap(); + assert_eq!(call.decl_id, expected_id) + } + _ => panic!("Expected expression Call not found"), + } + } } diff --git a/crates/nu-protocol/src/engine/engine_state.rs b/crates/nu-protocol/src/engine/engine_state.rs index cb8386e64..d02e895e0 100644 --- a/crates/nu-protocol/src/engine/engine_state.rs +++ b/crates/nu-protocol/src/engine/engine_state.rs @@ -744,9 +744,54 @@ pub struct StateWorkingSet<'a> { pub permanent_state: &'a EngineState, pub delta: StateDelta, pub external_commands: Vec>, - // Internal commands output that the next expression in the pipe will use to select a declaration - // that matches the name in the found output - pub found_outputs: Vec, + pub type_scope: TypeScope, +} + +/// A temporary placeholder for expression types. It is used to keep track of the input types +/// for each expression in a pipeline +pub struct TypeScope { + /// Layers that map the type inputs that are found in each parsed block + outputs: Vec>, + /// The last know output from a parsed block + last_output: Type, +} + +impl Default for TypeScope { + fn default() -> Self { + Self { + outputs: Vec::new(), + last_output: Type::Any, + } + } +} + +impl TypeScope { + pub fn get_previous(&self) -> &Type { + match self.outputs.last().and_then(|v| v.last()) { + Some(input) => input, + None => &Type::Any, + } + } + + pub fn get_last_output(&self) -> Type { + self.last_output.clone() + } + + pub fn add_type(&mut self, input: Type) { + match self.outputs.last_mut() { + Some(v) => v.push(input), + None => self.outputs.push(vec![input]), + } + } + + pub fn enter_scope(&mut self) { + self.outputs.push(Vec::new()) + } + + pub fn exit_scope(&mut self) -> Option> { + self.last_output = self.get_previous().clone(); + self.outputs.pop() + } } /// A delta (or change set) between the current global state and a possible future global state. Deltas @@ -871,7 +916,7 @@ impl<'a> StateWorkingSet<'a> { delta: StateDelta::new(permanent_state), permanent_state, external_commands: vec![], - found_outputs: vec![], + type_scope: TypeScope::default(), } } diff --git a/crates/nu-protocol/src/engine/overlay.rs b/crates/nu-protocol/src/engine/overlay.rs index dccfdf340..da50e9262 100644 --- a/crates/nu-protocol/src/engine/overlay.rs +++ b/crates/nu-protocol/src/engine/overlay.rs @@ -225,7 +225,10 @@ impl OverlayFrame { } pub fn get_decl(&self, name: &[u8], input: &Type) -> Option { - self.decls.get(&(name, input) as &dyn DeclKey).cloned() + match self.decls.get(&(name, input) as &dyn DeclKey) { + Some(decl) => Some(*decl), + None => self.decls.get(&(name, &Type::Any) as &dyn DeclKey).cloned(), + } } } diff --git a/crates/nu-protocol/src/ty.rs b/crates/nu-protocol/src/ty.rs index e85e7ba90..382764e42 100644 --- a/crates/nu-protocol/src/ty.rs +++ b/crates/nu-protocol/src/ty.rs @@ -95,7 +95,7 @@ impl Display for Type { Type::Any => write!(f, "any"), Type::Error => write!(f, "error"), Type::Binary => write!(f, "binary"), - Type::Custom(custom) => write!(f, "custom<{}>", custom), + Type::Custom(custom) => write!(f, "{}", custom), Type::Signature => write!(f, "signature"), } }