ag_grid_rs/
filter.rs

1//! Types pertaining to grid filtering.
2
3use ag_grid_core::imports::ObjectExt;
4use chrono::NaiveDateTime;
5use wasm_bindgen::JsCast;
6
7#[derive(Debug)]
8pub enum Comparator {
9    Equals,
10    NotEquals,
11    Contains,
12    NotContains,
13    StartsWith,
14    EndsWith,
15    LessThan,
16    LessThanOrEqual,
17    GreaterThan,
18    GreaterThanOrEqual,
19    InRange,
20    Blank,
21    NotBlank,
22    ChooseOne,
23}
24
25impl From<String> for Comparator {
26    fn from(v: String) -> Self {
27        match v.as_str() {
28            "equals" => Self::Equals,
29            "notEqual" => Self::NotEquals,
30            "contains" => Self::Contains,
31            "notContains" => Self::NotContains,
32            "startsWith" => Self::StartsWith,
33            "endsWith" => Self::EndsWith,
34            "lessThan" => Self::LessThan,
35            "lessThanOrEqual" => Self::LessThanOrEqual,
36            "greaterThan" => Self::GreaterThan,
37            "greaterThanOrEqual" => Self::GreaterThanOrEqual,
38            "inRange" => Self::InRange,
39            "blank" => Self::Blank,
40            "notBlank" => Self::NotBlank,
41            "empty" => Self::ChooseOne,
42            // This is the full set of options from the AG Grid library.
43            _ => unreachable!(),
44        }
45    }
46}
47
48#[derive(Debug)]
49pub enum FilterModelType {
50    Single(FilterModel),
51    Combined(CombinedFilterModel),
52}
53
54#[derive(Debug)]
55pub enum FilterModel {
56    Text(TextFilter),
57    Number(NumberFilter),
58    Date(DateFilter),
59}
60
61impl FilterModel {
62    pub fn from_object(obj: &ObjectExt) -> Self {
63        let filter_type = obj.get_string_unchecked("filterType");
64        match filter_type.as_str() {
65            "text" => FilterModel::Text(TextFilter::from_object(obj)),
66            "number" => FilterModel::Number(NumberFilter::from_object(obj)),
67            "date" => FilterModel::Date(DateFilter::from_object(obj)),
68            _ => unreachable!(),
69        }
70    }
71}
72
73impl CombinedFilterModel {
74    pub fn from_object(obj: &ObjectExt) -> Self {
75        let filter_type = obj.get_string_unchecked("filterType");
76        let operator = obj.get_string_unchecked("operator").into();
77        let c1 = obj.get("condition1").unchecked_into::<ObjectExt>();
78        let c2 = obj.get("condition2").unchecked_into::<ObjectExt>();
79        match filter_type.as_str() {
80            "text" => CombinedFilterModel::Text(CombinedTextFilter {
81                operator,
82                condition_1: TextFilter::from_object(&c1),
83                condition_2: TextFilter::from_object(&c2),
84            }),
85            "number" => CombinedFilterModel::Number(CombinedNumberFilter {
86                operator,
87                condition_1: NumberFilter::from_object(&c1),
88                condition_2: NumberFilter::from_object(&c2),
89            }),
90            "date" => CombinedFilterModel::Date(CombinedDateFilter {
91                operator,
92                condition_1: DateFilter::from_object(&c1),
93                condition_2: DateFilter::from_object(&c2),
94            }),
95
96            _ => unreachable!(),
97        }
98    }
99}
100
101#[derive(Debug)]
102pub enum CombinedFilterModel {
103    Text(CombinedTextFilter),
104    Number(CombinedNumberFilter),
105    Date(CombinedDateFilter),
106}
107
108/// Describe how to handle multiple conditions.
109#[derive(Debug)]
110pub enum JoinOperator {
111    /// Combine two given conditions using *and* semantics.
112    And,
113    /// Combine two given conditions using *or* semantics.
114    Or,
115}
116
117impl From<String> for JoinOperator {
118    fn from(v: String) -> Self {
119        match v.as_str() {
120            "AND" => Self::And,
121            "OR" => Self::Or,
122            // This is the complete list of operators as per AG Grid.
123            _ => unreachable!(),
124        }
125    }
126}
127
128#[derive(Debug)]
129pub struct TextFilter {
130    pub filter: Option<String>,
131    pub filter_to: Option<String>,
132    pub comparator: Option<Comparator>,
133}
134
135impl TextFilter {
136    pub fn from_object(obj: &ObjectExt) -> Self {
137        let comparator = obj.get_string("type").map(Comparator::from);
138        Self {
139            filter: obj.get_string("filter"),
140            filter_to: obj.get_string("filterTo"),
141            comparator,
142        }
143    }
144}
145
146#[derive(Debug)]
147pub struct NumberFilter {
148    pub filter: Option<f64>,
149    pub filter_to: Option<f64>,
150    pub comparator: Option<Comparator>,
151}
152
153impl NumberFilter {
154    pub fn from_object(obj: &ObjectExt) -> Self {
155        let comparator = obj.get_string("type").map(Comparator::from);
156        Self {
157            filter: obj.get_f64("filter"),
158            filter_to: obj.get_f64("filterTo"),
159            comparator,
160        }
161    }
162}
163
164#[derive(Debug)]
165pub struct DateFilter {
166    pub filter: Option<NaiveDateTime>,
167    pub filter_to: Option<NaiveDateTime>,
168    pub comparator: Option<Comparator>,
169}
170
171impl DateFilter {
172    pub fn from_object(obj: &ObjectExt) -> Self {
173        let comparator = obj.get_string("type").map(Comparator::from);
174        Self {
175            filter: obj.get_string("dateFrom").map(|dt| {
176                NaiveDateTime::parse_from_str(&dt, "%Y-%m-%d %H:%M:%S")
177                    .expect("Ag Grid should always pass a date in format 'YYYY-MM-DD hh:mm:ss'")
178            }),
179            filter_to: obj.get_string("dateFrom").map(|dt| {
180                NaiveDateTime::parse_from_str(&dt, "%Y-%m-%d %H:%M:%S")
181                    .expect("Ag Grid should always pass a date in format 'YYYY-MM-DD hh:mm:ss'")
182            }),
183            comparator,
184        }
185    }
186}
187
188#[derive(Debug)]
189pub struct CombinedTextFilter {
190    pub condition_1: TextFilter,
191    pub condition_2: TextFilter,
192    pub operator: JoinOperator,
193}
194
195#[derive(Debug)]
196pub struct CombinedNumberFilter {
197    pub condition_1: NumberFilter,
198    pub condition_2: NumberFilter,
199    pub operator: JoinOperator,
200}
201
202#[derive(Debug)]
203pub struct CombinedDateFilter {
204    pub condition_1: DateFilter,
205    pub condition_2: DateFilter,
206    pub operator: JoinOperator,
207}