use crate::dataframe::values::NuExpression; use crate::values::{ cant_convert_err, Column, CustomValueSupport, NuDataFrame, NuLazyFrame, PolarsPluginObject, PolarsPluginType, }; use crate::PolarsPlugin; use nu_plugin::{EngineInterface, EvaluatedCall, PluginCommand}; use nu_protocol::{ Category, Example, LabeledError, PipelineData, ShellError, Signature, Span, Type, Value, }; pub struct ExprSum; impl PluginCommand for ExprSum { type Plugin = PolarsPlugin; fn name(&self) -> &str { "polars sum" } fn description(&self) -> &str { "Creates a sum expression for an aggregation or aggregates columns to their sum value." } fn signature(&self) -> Signature { Signature::build(self.name()) .input_output_types(vec![ ( Type::Custom("expression".into()), Type::Custom("expression".into()), ), ( Type::Custom("dataframe".into()), Type::Custom("dataframe".into()), ), ]) .category(Category::Custom("dataframe".into())) } fn examples(&self) -> Vec { vec![ Example { description: "Sums all columns in a dataframe", example: "[[a b]; [6 2] [1 4] [4 1]] | polars into-df | polars sum | polars collect", 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)]), ], None, ) .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]] | polars into-df | polars group-by a | polars agg (polars col b | polars sum) | polars collect | polars sort-by a"#, 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)], ), ], None, ) .expect("simple df for test should not fail") .into_value(Span::test_data()), ), }, ] } fn run( &self, plugin: &Self::Plugin, engine: &EngineInterface, call: &EvaluatedCall, input: PipelineData, ) -> Result { let value = input.into_value(call.head)?; match PolarsPluginObject::try_from_value(plugin, &value)? { PolarsPluginObject::NuDataFrame(df) => command_lazy(plugin, engine, call, df.lazy()), PolarsPluginObject::NuLazyFrame(lazy) => command_lazy(plugin, engine, call, lazy), PolarsPluginObject::NuExpression(expr) => command_expr(plugin, engine, call, expr), _ => Err(cant_convert_err( &value, &[ PolarsPluginType::NuDataFrame, PolarsPluginType::NuLazyFrame, PolarsPluginType::NuExpression, ], )), } .map_err(LabeledError::from) } } fn command_expr( plugin: &PolarsPlugin, engine: &EngineInterface, call: &EvaluatedCall, expr: NuExpression, ) -> Result { NuExpression::from(expr.into_polars().sum()).to_pipeline_data(plugin, engine, call.head) } fn command_lazy( plugin: &PolarsPlugin, engine: &EngineInterface, call: &EvaluatedCall, lazy: NuLazyFrame, ) -> Result { let res: NuLazyFrame = lazy.to_polars().sum().into(); res.to_pipeline_data(plugin, engine, call.head) } #[cfg(test)] mod test { use super::*; use crate::test::test_polars_plugin_command; use nu_protocol::ShellError; #[test] fn test_examples() -> Result<(), ShellError> { test_polars_plugin_command(&ExprSum) } }