dgraph_query_lib/
condition.rs

1use crate::ToQueryString;
2use serde_json::Value;
3use crate::predicate::Variable;
4use itertools::Itertools;
5
6#[derive(Clone, Debug)]
7pub enum ConditionValue {
8    String(String),
9    StringArr(Vec<String>),
10    Regexp(String),
11    Literal(String),
12    NumArr(Vec<String>),
13    Val(Variable)
14}
15
16impl ConditionValue {
17    pub fn string(value: &str) -> ConditionValue {
18        ConditionValue::String(value.to_string())
19    }
20
21    pub fn regexp(value: &str) -> ConditionValue {
22        ConditionValue::Regexp(value.to_string())
23    }
24
25    pub fn literal(value: &str) -> ConditionValue {
26        ConditionValue::Literal(value.to_string())
27    }
28
29    pub fn literal_int(value: i64) -> ConditionValue {
30        ConditionValue::Literal(format!("{}", value))
31    }
32
33    pub fn string_arr(value: Vec<&str>) -> ConditionValue {
34        ConditionValue::StringArr(value.into_iter().map(|item| item.to_string()).collect())
35    }
36
37    pub fn num_arr(value: Vec<i64>) -> ConditionValue {
38        ConditionValue::NumArr(value.into_iter().map(|value| format!("{}", value)).collect())
39    }
40}
41
42impl ToQueryString for ConditionValue {
43    fn to_query_string(&self) -> String {
44        match self {
45            ConditionValue::Regexp(value) | ConditionValue::Literal(value) => format!("{}", value),
46            ConditionValue::String(value) => Value::String(value.clone()).to_string(),
47            ConditionValue::Val(value) => format!("val({})", value.get_name()),
48            ConditionValue::StringArr(value) => format!("[{}]", value.iter().map(|item| Value::String(item.to_string()).to_string()).join(", ")),
49            ConditionValue::NumArr(value) => format!("[{}]", value.iter().join(", "))
50        }
51    }
52}
53
54#[derive(Clone, Debug)]
55pub enum Condition {
56    UID(String),
57    EQ(String, ConditionValue),
58    GE(String, ConditionValue),
59    GT(String, ConditionValue),
60    LE(String, ConditionValue),
61    LT(String, ConditionValue),
62    HAS(String),
63    REGEXP(String, ConditionValue),
64    AND(Box<Condition>, Box<Condition>),
65    OR(Box<Condition>, Box<Condition>),
66    NOT(Box<Condition>),
67}
68
69impl Condition {
70    pub fn len(value: &str) -> String {
71        format!("len({})", value)
72    }
73
74    pub fn has(value: &str) -> Condition {
75        Condition::HAS(value.to_string())
76    }
77
78    pub fn uid(value: &str) -> Condition {
79        Condition::UID(value.to_string())
80    }
81}
82
83impl ToQueryString for Condition {
84    fn to_query_string(&self) -> String {
85        match self {
86            Condition::UID(id) => format!("uid({id})", id = id),
87            Condition::EQ(predicate, value) => format!("eq({predicate}, {value})", predicate = predicate, value = value.to_query_string()),
88            Condition::GE(predicate, value) => format!("ge({predicate}, {value})", predicate = predicate, value = value.to_query_string()),
89            Condition::GT(predicate, value) => format!("gt({predicate}, {value})", predicate = predicate, value = value.to_query_string()),
90            Condition::LE(predicate, value) => format!("le({predicate}, {value})", predicate = predicate, value = value.to_query_string()),
91            Condition::LT(predicate, value) => format!("lt({predicate}, {value})", predicate = predicate, value = value.to_query_string()),
92            Condition::HAS(predicate) => format!("has({predicate})", predicate = predicate),
93            Condition::REGEXP(predicate, ConditionValue::Regexp(regex_val)) => format!("regexp({predicate}, /{regex}/)", predicate = predicate, regex = regex_val),
94            Condition::AND(left, right) => format!("({left} AND {right})", left = left.to_query_string(), right = right.to_query_string()),
95            Condition::OR(left, right) => format!("({left} OR {right})", left = left.to_query_string(), right = right.to_query_string()),
96            Condition::NOT(condition) => format!("(not {condition})", condition = condition.to_query_string()),
97            _ => panic!("Invalid condition: {:?}", self)
98        }
99    }
100}