summaryrefslogtreecommitdiffstats
path: root/vendor/jsonpath_lib/src/select/cmp.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/jsonpath_lib/src/select/cmp.rs')
-rw-r--r--vendor/jsonpath_lib/src/select/cmp.rs335
1 files changed, 335 insertions, 0 deletions
diff --git a/vendor/jsonpath_lib/src/select/cmp.rs b/vendor/jsonpath_lib/src/select/cmp.rs
new file mode 100644
index 000000000..209e67298
--- /dev/null
+++ b/vendor/jsonpath_lib/src/select/cmp.rs
@@ -0,0 +1,335 @@
+use array_tool::vec::{Intersect, Union};
+use serde_json::Value;
+
+pub(super) trait Cmp {
+ fn cmp_bool(&self, v1: bool, v2: bool) -> bool;
+
+ fn cmp_f64(&self, v1: f64, v2: f64) -> bool;
+
+ fn cmp_string(&self, v1: &str, v2: &str) -> bool;
+
+ fn cmp_json<'a>(&self, v1: &[&'a Value], v2: &[&'a Value]) -> Vec<&'a Value>;
+
+ fn default(&self) -> bool {
+ false
+ }
+}
+
+pub(super) struct CmpEq;
+
+impl Cmp for CmpEq {
+ fn cmp_bool(&self, v1: bool, v2: bool) -> bool {
+ v1 == v2
+ }
+
+ fn cmp_f64(&self, v1: f64, v2: f64) -> bool {
+ (v1 - v2).abs() == 0_f64
+ }
+
+ fn cmp_string(&self, v1: &str, v2: &str) -> bool {
+ v1 == v2
+ }
+
+ fn cmp_json<'a>(&self, v1: &[&'a Value], v2: &[&'a Value]) -> Vec<&'a Value> {
+ v1.to_vec().intersect(v2.to_vec())
+ }
+}
+
+pub(super) struct CmpNe;
+
+impl Cmp for CmpNe {
+ fn cmp_bool(&self, v1: bool, v2: bool) -> bool {
+ v1 != v2
+ }
+
+ fn cmp_f64(&self, v1: f64, v2: f64) -> bool {
+ (v1 - v2).abs() != 0_f64
+ }
+
+ fn cmp_string(&self, v1: &str, v2: &str) -> bool {
+ v1 != v2
+ }
+
+ fn cmp_json<'a>(&self, v1: &[&'a Value], v2: &[&'a Value]) -> Vec<&'a Value> {
+ v1.to_vec().intersect_if(v2.to_vec(), |a, b| a != b)
+ }
+}
+
+pub(super) struct CmpGt;
+
+impl Cmp for CmpGt {
+ fn cmp_bool(&self, v1: bool, v2: bool) -> bool {
+ v1 & !v2
+ }
+
+ fn cmp_f64(&self, v1: f64, v2: f64) -> bool {
+ v1 > v2
+ }
+
+ fn cmp_string(&self, v1: &str, v2: &str) -> bool {
+ v1 > v2
+ }
+
+ fn cmp_json<'a>(&self, _: &[&'a Value], _: &[&'a Value]) -> Vec<&'a Value> {
+ Vec::new()
+ }
+}
+
+pub(super) struct CmpGe;
+
+impl Cmp for CmpGe {
+ fn cmp_bool(&self, v1: bool, v2: bool) -> bool {
+ v1 >= v2
+ }
+
+ fn cmp_f64(&self, v1: f64, v2: f64) -> bool {
+ v1 >= v2
+ }
+
+ fn cmp_string(&self, v1: &str, v2: &str) -> bool {
+ v1 >= v2
+ }
+
+ fn cmp_json<'a>(&self, _: &[&'a Value], _: &[&'a Value]) -> Vec<&'a Value> {
+ Vec::new()
+ }
+}
+
+pub(super) struct CmpLt;
+
+impl Cmp for CmpLt {
+ fn cmp_bool(&self, v1: bool, v2: bool) -> bool {
+ !v1 & v2
+ }
+
+ fn cmp_f64(&self, v1: f64, v2: f64) -> bool {
+ v1 < v2
+ }
+
+ fn cmp_string(&self, v1: &str, v2: &str) -> bool {
+ v1 < v2
+ }
+
+ fn cmp_json<'a>(&self, _: &[&'a Value], _: &[&'a Value]) -> Vec<&'a Value> {
+ Vec::new()
+ }
+}
+
+pub(super) struct CmpLe;
+
+impl Cmp for CmpLe {
+ fn cmp_bool(&self, v1: bool, v2: bool) -> bool {
+ v1 <= v2
+ }
+
+ fn cmp_f64(&self, v1: f64, v2: f64) -> bool {
+ v1 <= v2
+ }
+
+ fn cmp_string(&self, v1: &str, v2: &str) -> bool {
+ v1 <= v2
+ }
+
+ fn cmp_json<'a>(&self, _: &[&'a Value], _: &[&'a Value]) -> Vec<&'a Value> {
+ Vec::new()
+ }
+}
+
+pub(super) struct CmpAnd;
+
+impl Cmp for CmpAnd {
+ fn cmp_bool(&self, v1: bool, v2: bool) -> bool {
+ v1 && v2
+ }
+
+ fn cmp_f64(&self, _v1: f64, _v2: f64) -> bool {
+ true
+ }
+
+ fn cmp_string(&self, v1: &str, v2: &str) -> bool {
+ !v1.is_empty() && !v2.is_empty()
+ }
+
+ fn cmp_json<'a>(&self, v1: &[&'a Value], v2: &[&'a Value]) -> Vec<&'a Value> {
+ v1.to_vec().intersect(v2.to_vec())
+ }
+}
+
+pub(super) struct CmpOr;
+
+impl Cmp for CmpOr {
+ fn cmp_bool(&self, v1: bool, v2: bool) -> bool {
+ v1 || v2
+ }
+
+ fn cmp_f64(&self, _v1: f64, _v2: f64) -> bool {
+ true
+ }
+
+ fn cmp_string(&self, v1: &str, v2: &str) -> bool {
+ !v1.is_empty() || !v2.is_empty()
+ }
+
+ fn cmp_json<'a>(&self, v1: &[&'a Value], v2: &[&'a Value]) -> Vec<&'a Value> {
+ v1.to_vec().union(v2.to_vec())
+ }
+}
+
+
+#[cfg(test)]
+mod cmp_inner_tests {
+ use serde_json::Value;
+
+ use select::cmp::*;
+
+ #[test]
+ fn cmp_eq() {
+ let cmp_fn = CmpEq;
+ assert_eq!(cmp_fn.default(), false);
+ assert_eq!(cmp_fn.cmp_bool(true, false), false);
+ assert_eq!(cmp_fn.cmp_bool(true, true), true);
+ assert_eq!(cmp_fn.cmp_f64(0.1, 0.1), true);
+ assert_eq!(cmp_fn.cmp_f64(0.1, 0.2), false);
+ assert_eq!(cmp_fn.cmp_string("1", "1"), true);
+ assert_eq!(cmp_fn.cmp_string("1", "2"), false);
+ }
+
+ #[test]
+ fn cmp_ne() {
+ let cmp_fn = CmpNe;
+ assert_eq!(cmp_fn.default(), false);
+ assert_eq!(cmp_fn.cmp_bool(true, false), true);
+ assert_eq!(cmp_fn.cmp_bool(true, true), false);
+ assert_eq!(cmp_fn.cmp_f64(0.1, 0.1), false);
+ assert_eq!(cmp_fn.cmp_f64(0.1, 0.2), true);
+ assert_eq!(cmp_fn.cmp_string("1", "1"), false);
+ assert_eq!(cmp_fn.cmp_string("1", "2"), true);
+ }
+
+ #[test]
+ fn cmp_gt() {
+ let cmp_fn = CmpGt;
+ assert_eq!(cmp_fn.default(), false);
+ assert_eq!(cmp_fn.cmp_bool(true, false), true);
+ assert_eq!(cmp_fn.cmp_bool(true, true), false);
+ assert_eq!(cmp_fn.cmp_f64(0.2, 0.1), true);
+ assert_eq!(cmp_fn.cmp_f64(0.1, 0.2), false);
+ assert_eq!(cmp_fn.cmp_string("a", "a"), false);
+ assert_eq!(cmp_fn.cmp_string("b", "a"), true);
+ assert_eq!(cmp_fn.cmp_string("1", "2"), false);
+ }
+
+ #[test]
+ fn cmp_ge() {
+ let cmp_fn = CmpGe;
+ assert_eq!(cmp_fn.default(), false);
+ assert_eq!(cmp_fn.cmp_bool(true, false), true);
+ assert_eq!(cmp_fn.cmp_bool(true, true), true);
+ assert_eq!(cmp_fn.cmp_f64(0.2, 0.1), true);
+ assert_eq!(cmp_fn.cmp_f64(0.1, 0.1), true);
+ assert_eq!(cmp_fn.cmp_f64(0.1, 0.2), false);
+ assert_eq!(cmp_fn.cmp_string("1", "1"), true);
+ assert_eq!(cmp_fn.cmp_string("ab", "a"), true);
+ assert_eq!(cmp_fn.cmp_string("1", "2"), false);
+ }
+
+ #[test]
+ fn cmp_lt() {
+ let cmp_fn = CmpLt;
+ assert_eq!(cmp_fn.default(), false);
+ assert_eq!(cmp_fn.cmp_bool(true, false), false);
+ assert_eq!(cmp_fn.cmp_bool(false, true), true);
+ assert_eq!(cmp_fn.cmp_bool(true, true), false);
+ assert_eq!(cmp_fn.cmp_bool(false, false), false);
+ assert_eq!(cmp_fn.cmp_f64(0.1, 0.2), true);
+ assert_eq!(cmp_fn.cmp_f64(0.1, 0.1), false);
+ assert_eq!(cmp_fn.cmp_f64(0.2, 0.1), false);
+ assert_eq!(cmp_fn.cmp_string("a", "a"), false);
+ assert_eq!(cmp_fn.cmp_string("ab", "b"), true);
+ assert_eq!(cmp_fn.cmp_string("1", "2"), true);
+ }
+
+ #[test]
+ fn cmp_le() {
+ let cmp_fn = CmpLe;
+ assert_eq!(cmp_fn.default(), false);
+ assert_eq!(cmp_fn.cmp_bool(true, false), false);
+ assert_eq!(cmp_fn.cmp_bool(false, true), true);
+ assert_eq!(cmp_fn.cmp_bool(true, true), true);
+ assert_eq!(cmp_fn.cmp_bool(false, false), true);
+ assert_eq!(cmp_fn.cmp_f64(0.1, 0.2), true);
+ assert_eq!(cmp_fn.cmp_f64(0.1, 0.1), true);
+ assert_eq!(cmp_fn.cmp_f64(0.2, 0.1), false);
+ assert_eq!(cmp_fn.cmp_string("a", "a"), true);
+ assert_eq!(cmp_fn.cmp_string("ab", "b"), true);
+ assert_eq!(cmp_fn.cmp_string("abd", "abc"), false);
+ assert_eq!(cmp_fn.cmp_string("1", "2"), true);
+ }
+
+ #[test]
+ fn cmp_and() {
+ let cmp_fn = CmpAnd;
+ assert_eq!(cmp_fn.default(), false);
+ assert_eq!(cmp_fn.cmp_bool(true, false), false);
+ assert_eq!(cmp_fn.cmp_bool(false, true), false);
+ assert_eq!(cmp_fn.cmp_bool(true, true), true);
+ assert_eq!(cmp_fn.cmp_bool(false, false), false);
+ assert_eq!(cmp_fn.cmp_f64(0.0, 0.0), true);
+ assert_eq!(cmp_fn.cmp_string("a", "a"), true);
+ }
+
+ #[test]
+ fn cmp_or() {
+ let cmp_fn = CmpOr;
+ assert_eq!(cmp_fn.default(), false);
+ assert_eq!(cmp_fn.cmp_bool(true, false), true);
+ assert_eq!(cmp_fn.cmp_bool(false, true), true);
+ assert_eq!(cmp_fn.cmp_bool(true, true), true);
+ assert_eq!(cmp_fn.cmp_bool(false, false), false);
+ assert_eq!(cmp_fn.cmp_f64(0.0, 0.0), true);
+ assert_eq!(cmp_fn.cmp_string("a", "a"), true);
+ }
+
+ #[test]
+ fn cmp_json() {
+ let v1 = Value::Bool(true);
+ let v2 = Value::String("1".to_string());
+ let left = [&v1, &v2];
+ let right = [&v1, &v2];
+ let empty: Vec<&Value> = Vec::new();
+
+ assert_eq!(CmpEq.cmp_json(&left, &right), left.to_vec());
+ assert_eq!(CmpNe.cmp_json(&left, &right), left.to_vec());
+ assert_eq!(CmpGt.cmp_json(&left, &right), empty);
+ assert_eq!(CmpGe.cmp_json(&left, &right), empty);
+ assert_eq!(CmpLt.cmp_json(&left, &right), empty);
+ assert_eq!(CmpLe.cmp_json(&left, &right), empty);
+ assert_eq!(CmpAnd.cmp_json(&left, &right), left.to_vec());
+ assert_eq!(CmpOr.cmp_json(&left, &right), left.to_vec());
+
+ assert_eq!(
+ CmpEq.cmp_json(&[&Value::Bool(true)], &[&Value::Bool(true)]),
+ vec![&Value::Bool(true)]
+ );
+ assert_eq!(
+ CmpEq.cmp_json(&[&Value::Bool(true)], &[&Value::Bool(false)]),
+ empty
+ );
+ assert_eq!(
+ CmpNe.cmp_json(&[&Value::Bool(true)], &[&Value::Bool(true)]),
+ empty
+ );
+ assert_eq!(
+ CmpNe.cmp_json(&[&Value::Bool(false)], &[&Value::Bool(true)]),
+ vec![&Value::Bool(false)]
+ );
+ assert_eq!(
+ CmpAnd.cmp_json(&[&Value::Bool(true)], &[&Value::Bool(true)]),
+ vec![&Value::Bool(true)]
+ );
+ assert_eq!(
+ CmpOr.cmp_json(&[&Value::Bool(true)], &[&Value::Bool(false)]),
+ vec![&Value::Bool(true), &Value::Bool(false)]
+ );
+ }
+}