Add Xor to polars plugin nu_expressions (#15249)

solution for #15242 ,  based on PR #15248 .

Allows doing this:

```
~/Projects/nushell> [[a, b]; [1., 2.], [3.,3.], [4., 6.]] | polars into-df | polars filter (((polars col a) < 2) xor ((polars col b) > 5))
╭───┬──────┬──────╮
│ # │  a   │  b   │
├───┼──────┼──────┤
│ 0 │ 1.00 │ 2.00 │
│ 1 │ 4.00 │ 6.00 │
╰───┴──────┴──────╯
```
This commit is contained in:
Matthias Meschede 2025-03-05 17:03:35 +01:00 committed by GitHub
parent 49f92e9090
commit 88bbe4abaa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -7,7 +7,7 @@ use std::ops::{Add, Div, Mul, Rem, Sub};
use super::NuExpression;
use nu_plugin::EngineInterface;
use nu_protocol::{
ast::{Comparison, Math, Operator},
ast::{Boolean, Comparison, Math, Operator},
CustomValue, ShellError, Span, Type, Value,
};
use polars::prelude::Expr;
@ -133,6 +133,21 @@ fn with_operator(
.apply_with_expr(right.clone(), Expr::lt_eq)
.cache(plugin, engine, lhs_span)?
.into_value(lhs_span)),
Operator::Boolean(Boolean::And) => Ok(left
.clone()
.apply_with_expr(right.clone(), Expr::logical_and)
.cache(plugin, engine, lhs_span)?
.into_value(lhs_span)),
Operator::Boolean(Boolean::Or) => Ok(left
.clone()
.apply_with_expr(right.clone(), Expr::logical_or)
.cache(plugin, engine, lhs_span)?
.into_value(lhs_span)),
Operator::Boolean(Boolean::Xor) => Ok(left
.clone()
.apply_with_expr(right.clone(), logical_xor)
.cache(plugin, engine, lhs_span)?
.into_value(lhs_span)),
op => Err(ShellError::OperatorUnsupportedType {
op,
unsupported: Type::Custom(TYPE_NAME.into()),
@ -143,6 +158,11 @@ fn with_operator(
}
}
pub fn logical_xor(a: Expr, b: Expr) -> Expr {
(a.clone().or(b.clone())) // A OR B
.and((a.and(b)).not()) // AND with NOT (A AND B)
}
fn apply_arithmetic<F>(
plugin: &PolarsPlugin,
engine: &EngineInterface,