nushell/src/evaluate/operator.rs
Belhorma Bendebiche 8f9dd6516e 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.
2019-12-02 11:02:57 -08:00

38 lines
1.1 KiB
Rust

use crate::data::value;
use nu_parser::Operator;
use nu_protocol::{Primitive, ShellTypeName, UntaggedValue, Value};
use std::ops::Not;
pub fn apply_operator(
op: &Operator,
left: &Value,
right: &Value,
) -> Result<UntaggedValue, (&'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: &UntaggedValue,
right: &UntaggedValue,
) -> Result<bool, (&'static str, &'static str)> {
if let (
UntaggedValue::Primitive(Primitive::String(l)),
UntaggedValue::Primitive(Primitive::String(r)),
) = (left, right)
{
Ok(l.contains(r))
} else {
Err((left.type_name(), right.type_name()))
}
}