diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-03-15 15:27:36 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-03-15 15:27:36 +0100 |
| commit | 77d153d315a2a5909840ebcd47491e4cef14428b (patch) | |
| tree | 0886afd2ac4b03facb7c33a4e59924e30f55fd41 /src/eval/ops.rs | |
| parent | ae0a56cdffa515ed6bb7cb566c025cc66ff00f33 (diff) | |
Add `in` and `not in` operators
Diffstat (limited to 'src/eval/ops.rs')
| -rw-r--r-- | src/eval/ops.rs | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/src/eval/ops.rs b/src/eval/ops.rs index 04a13fd1..6a8f5284 100644 --- a/src/eval/ops.rs +++ b/src/eval/ops.rs @@ -335,3 +335,31 @@ pub fn compare(lhs: &Value, rhs: &Value) -> Option<Ordering> { _ => Option::None, } } + +/// Test whether one value is "in" another one. +pub fn in_(lhs: Value, rhs: Value) -> StrResult<Value> { + if let Some(b) = contains(&lhs, &rhs) { + Ok(Bool(b)) + } else { + mismatch!("cannot apply 'in' to {} and {}", lhs, rhs) + } +} + +/// Test whether one value is "not in" another one. +pub fn not_in(lhs: Value, rhs: Value) -> StrResult<Value> { + if let Some(b) = contains(&lhs, &rhs) { + Ok(Bool(!b)) + } else { + mismatch!("cannot apply 'not in' to {} and {}", lhs, rhs) + } +} + +/// Test for containment. +pub fn contains(lhs: &Value, rhs: &Value) -> Option<bool> { + Some(match (lhs, rhs) { + (Value::Str(a), Value::Str(b)) => b.contains(a.as_str()), + (Value::Str(a), Value::Dict(b)) => b.contains_key(a), + (a, Value::Array(b)) => b.contains(a), + _ => return Option::None, + }) +} |
