summaryrefslogtreecommitdiff
path: root/src/eval/ops.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-03-15 15:27:36 +0100
committerLaurenz <laurmaedje@gmail.com>2022-03-15 15:27:36 +0100
commit77d153d315a2a5909840ebcd47491e4cef14428b (patch)
tree0886afd2ac4b03facb7c33a4e59924e30f55fd41 /src/eval/ops.rs
parentae0a56cdffa515ed6bb7cb566c025cc66ff00f33 (diff)
Add `in` and `not in` operators
Diffstat (limited to 'src/eval/ops.rs')
-rw-r--r--src/eval/ops.rs28
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,
+ })
+}