derive_sql/selectable/filter/
and.rs

1//! Implement `AND` combination of filter.
2use super::*;
3
4pub struct And<T, U, V, W, X, Y>
5where T: FilterTrait,
6      U: FilterTrait,
7      V: FilterTrait,
8      W: FilterTrait,
9      X: FilterTrait,
10      Y: FilterTrait,
11{
12  t: T,
13  u: U,
14  v: Option<V>,
15  w: Option<W>,
16  x: Option<X>,
17  y: Option<Y>,
18}
19
20impl<T, U> std::convert::From<(T, U)> for And<T, U, T, T, T, T>
21where T: FilterTrait, U: FilterTrait {
22  fn from((t, u): (T, U)) -> Self {
23    And { t, u, v: None, w: None, x: None, y: None }
24  }
25}
26
27impl<T, U, V> std::convert::From<(T, U, V)> for And<T, U, V, T, T, T>
28where T: FilterTrait, U: FilterTrait, V: FilterTrait {
29  fn from((t, u, v): (T, U, V)) -> Self {
30    And { t, u, v: Some(v), w: None, x: None, y: None }
31  }
32}
33
34impl<T, U, V, W> std::convert::From<(T, U, V, W)> for And<T, U, V, W, T, T>
35where T: FilterTrait, U: FilterTrait, V: FilterTrait, W: FilterTrait {
36  fn from((t, u, v, w): (T, U, V, W)) -> Self {
37    And { t, u, v: Some(v), w: Some(w), x: None, y: None }
38  }
39}
40
41impl<T, U, V, W, X> std::convert::From<(T, U, V, W, X)> for And<T, U, V, W, X, T>
42where T: FilterTrait, U: FilterTrait, V: FilterTrait, W: FilterTrait, X: FilterTrait {
43  fn from((t, u, v, w, x): (T, U, V, W, X)) -> Self {
44    And { t, u, v: Some(v), w: Some(w), x: Some(x), y: None }
45  }
46}
47
48impl<T, U, V, W, X, Y> std::convert::From<(T, U, V, W, X, Y)> for And<T, U, V, W, X, Y>
49where T: FilterTrait, U: FilterTrait, V: FilterTrait, W: FilterTrait, X: FilterTrait, Y: FilterTrait {
50  fn from((t, u, v, w, x, y): (T, U, V, W, X, Y)) -> Self {
51    And { t, u, v: Some(v), w: Some(w), x: Some(x), y: Some(y) }
52  }
53}
54
55impl<T, U, V, W, X, Y> FilterTrait for And<T, U, V, W, X, Y>
56where T: FilterTrait, U: FilterTrait, V: FilterTrait,
57      W: FilterTrait, X: FilterTrait, Y: FilterTrait,
58{
59  fn filter(&self) -> String {
60    let a = self.t.filter(); let b = self.u.filter();
61    match self.v.as_ref().map(|v| v.filter()) {
62      Some(c) => match self.w.as_ref().map(|w| w.filter()) {
63        Some(d) => match self.x.as_ref().map(|x| x.filter()) {
64          Some(e) => match self.y.as_ref().map(|y| y.filter()) {
65            Some(f) => format!("( {a} AND {b} AND {c} AND {d} AND {e} AND {f} )"),
66            None => format!("( {a} AND {b} AND {c} AND {d} AND {e} )"),
67          },
68          None => format!("( {a} AND {b} AND {c} AND {d} )"),
69        },
70        None => format!("( {a} AND {b} AND {c} )"),
71      },
72      None => format!("( {a} AND {b} )"),
73    }
74  }
75}
76
77#[cfg(test)]
78mod tests {
79  use super::*;
80
81  struct WordOne { }
82  impl FilterTrait for WordOne {
83    fn filter(&self) -> String {
84      "1".to_string()
85    }
86  }
87
88  struct WordHouse { }
89  impl FilterTrait for WordHouse {
90    fn filter(&self) -> String {
91      "House".to_string()
92    }
93  }
94
95  #[test]
96  fn it_combines_filter() -> DeriveSqlResult<()> {
97    let and: And<_, _, _, _, _, _> = (WordOne {}, WordOne {}).into();
98    assert!(and.filter().eq("( 1 AND 1 )"));
99
100    let and: And<_, _, _, _, _, _> = (WordOne {}, WordHouse {}, WordOne {}).into();
101    assert!(and.filter().eq("( 1 AND House AND 1 )"));
102
103    let and: And<_, _, _, _, _, _> = (WordOne {}, WordHouse {}, WordHouse {}, WordOne {}).into();
104    assert!(and.filter().eq("( 1 AND House AND House AND 1 )"));
105
106    let and: And<_, _, _, _, _, _> = (WordOne {}, WordHouse {}, WordHouse {}, WordOne {}, WordHouse {}, ).into();
107    assert!(and.filter().eq("( 1 AND House AND House AND 1 AND House )"));
108
109    let and: And<_, _, _, _, _, _> = (WordOne {}, WordHouse {}, WordHouse {}, WordOne {}, WordHouse {}, WordHouse {}).into();
110    assert!(and.filter().eq("( 1 AND House AND House AND 1 AND House AND House )"));
111
112    Ok(())
113  }
114}