summaryrefslogtreecommitdiff
path: root/include/llmr/map/filter_expression.hpp
blob: 50e6ce1d78f20a3684361976cfe25f378b365ab6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#ifndef LLMR_MAP_FILTER_EXPRESSION
#define LLMR_MAP_FILTER_EXPRESSION

#include <llmr/style/value.hpp>
#include <llmr/util/recursive_wrapper.hpp>

#include <vector>
#include <string>

namespace llmr {

enum class FilterOperator {
    Equal,
    NotEqual,
    Greater,
    GreaterEqual,
    Less,
    LessEqual
};

enum class ExpressionOperator {
    Or,
    And
};


inline FilterOperator filterOperatorType(const std::string &op) {
    if (op == "!=" || op == "not") {
        return FilterOperator::NotEqual;
    } else if (op == "==" || op == "eq") {
        return FilterOperator::Equal;
    } else if (op == ">" || op == "gt") {
        return FilterOperator::Greater;
    } else if (op == ">=" || op == "gte") {
        return FilterOperator::GreaterEqual;
    } else if (op == "<" || op == "lt") {
        return FilterOperator::Less;
    } else if (op == "<=" || op == "lte") {
        return FilterOperator::LessEqual;
    } else {
        fprintf(stderr, "[WARNING] filter operator '%s' unrecognized\n", op.c_str());
        return FilterOperator::Equal;
    }
}

inline ExpressionOperator expressionOperatorType(const std::string &op) {
    if (op == "&&" || op == "and") {
        return ExpressionOperator::And;
    } else if (op == "||" || op == "or") {
        return ExpressionOperator::Or;
    } else {
        fprintf(stderr, "[WARNING] expression operator '%s' unrecognized\n", op.c_str());
        return ExpressionOperator::Or;
    }
}


class PropertyFilter;
class PropertyExpression;

typedef util::variant<
    util::recursive_wrapper<PropertyFilter>,
    util::recursive_wrapper<PropertyExpression>,
    std::true_type
> PropertyFilterExpression;


class PropertyFilter {
public:
    inline PropertyFilter(const std::string &field, FilterOperator op, const Value &value) : field(field), op(op), value(value) {};
    inline PropertyFilter(PropertyFilter &&filter)
        : field(std::move(filter.field)),
          op(filter.op),
          value(std::move(filter.value)) {
    }

    // Returns true if the filter passes, even if the key is missing.
    inline bool isMissingFieldOkay() const {
        switch (op) {
        case FilterOperator::NotEqual:
            return true;
        default:
            return false;
        }
    }

    inline bool compare(const Value &other) const {
        switch (op) {
        case FilterOperator::Equal:
            return util::relaxed_equal(other, value);
        case FilterOperator::NotEqual:
            return !util::relaxed_equal(other, value);
        case FilterOperator::Greater:
            return util::relaxed_greater(other, value);
        case FilterOperator::GreaterEqual:
            return util::relaxed_greater_equal(other, value);
        case FilterOperator::Less:
            return util::relaxed_less(other, value);
        case FilterOperator::LessEqual:
            return util::relaxed_less_equal(other, value);
        default:
            return false;
        }
    }

public:
    std::string field;
    FilterOperator op = FilterOperator::Equal;
    Value value;
};

class PropertyExpression {
public:
    inline PropertyExpression() {}
    inline PropertyExpression(PropertyExpression &&expression)
        : op(expression.op),
          operands(std::move(expression.operands)) {
    }

public:
    ExpressionOperator op = ExpressionOperator::Or;
    std::vector<PropertyFilterExpression> operands;
};


}

#endif