mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 01:35:02 +02:00
Add =~
and !~
operators on strings
`left =~ right` return true if left contains right, using Rust's `String::contains`. `!~` is the negated version. A new `apply_operator` function is added which decouples evaluation from `Value::compare`. This returns a `Value` and opens the door to implementing `+` for example, though it wouldn't be useful immediately. The `operator!` macro had to be changed slightly as it would choke on `~` in arguments.
This commit is contained in:
@ -1,5 +1,6 @@
|
||||
use crate::data::base::Block;
|
||||
use crate::errors::ArgumentError;
|
||||
use crate::evaluate::operator::apply_operator;
|
||||
use crate::parser::hir::path::{ColumnPath, RawPathMember};
|
||||
use crate::parser::{
|
||||
hir::{self, Expression, RawExpression},
|
||||
@ -79,8 +80,8 @@ pub(crate) fn evaluate_baseline_expr(
|
||||
|
||||
trace!("left={:?} right={:?}", left.item, right.item);
|
||||
|
||||
match left.compare(binary.op(), &*right) {
|
||||
Ok(result) => Ok(Value::boolean(result).tagged(tag)),
|
||||
match apply_operator(binary.op(), &*left, &*right) {
|
||||
Ok(result) => Ok(result.tagged(tag)),
|
||||
Err((left_type, right_type)) => Err(ShellError::coerce_error(
|
||||
left_type.spanned(binary.left().span),
|
||||
right_type.spanned(binary.right().span),
|
||||
|
@ -1,3 +1,4 @@
|
||||
pub(crate) mod evaluator;
|
||||
pub(crate) mod operator;
|
||||
|
||||
pub(crate) use evaluator::{evaluate_baseline_expr, Scope};
|
||||
|
33
src/evaluate/operator.rs
Normal file
33
src/evaluate/operator.rs
Normal file
@ -0,0 +1,33 @@
|
||||
use crate::data::Primitive;
|
||||
use crate::data::Value;
|
||||
use crate::parser::Operator;
|
||||
use crate::traits::ShellTypeName;
|
||||
use std::ops::Not;
|
||||
|
||||
pub fn apply_operator(
|
||||
op: &Operator,
|
||||
left: &Value,
|
||||
right: &Value,
|
||||
) -> Result<Value, (&'static str, &'static str)> {
|
||||
match *op {
|
||||
Operator::Equal
|
||||
| Operator::NotEqual
|
||||
| Operator::LessThan
|
||||
| Operator::GreaterThan
|
||||
| Operator::LessThanOrEqual
|
||||
| Operator::GreaterThanOrEqual => left.compare(op, right).map(Value::boolean),
|
||||
Operator::Dot => Ok(Value::boolean(false)),
|
||||
Operator::Contains => contains(left, right).map(Value::boolean),
|
||||
Operator::NotContains => contains(left, right).map(Not::not).map(Value::boolean),
|
||||
}
|
||||
}
|
||||
|
||||
fn contains(left: &Value, right: &Value) -> Result<bool, (&'static str, &'static str)> {
|
||||
if let (Value::Primitive(Primitive::String(l)), Value::Primitive(Primitive::String(r))) =
|
||||
(left, right)
|
||||
{
|
||||
Ok(l.contains(r))
|
||||
} else {
|
||||
Err((left.type_name(), right.type_name()))
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user