1use super::*;
3
4pub struct And<T, U, V, W, X, Y>
5where T: traits::FlavoredFilter,
6 U: traits::FlavoredFilter,
7 V: traits::FlavoredFilter,
8 W: traits::FlavoredFilter,
9 X: traits::FlavoredFilter,
10 Y: traits::FlavoredFilter,
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: traits::FlavoredFilter, U: traits::FlavoredFilter {
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: traits::FlavoredFilter, U: traits::FlavoredFilter, V: traits::FlavoredFilter {
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: traits::FlavoredFilter, U: traits::FlavoredFilter, V: traits::FlavoredFilter, W: traits::FlavoredFilter {
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: traits::FlavoredFilter, U: traits::FlavoredFilter, V: traits::FlavoredFilter, W: traits::FlavoredFilter, X: traits::FlavoredFilter {
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: traits::FlavoredFilter, U: traits::FlavoredFilter, V: traits::FlavoredFilter, W: traits::FlavoredFilter, X: traits::FlavoredFilter, Y: traits::FlavoredFilter {
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> traits::FlavoredFilter for And<T, U, V, W, X, Y>
56where T: traits::FlavoredFilter, U: traits::FlavoredFilter, V: traits::FlavoredFilter,
57 W: traits::FlavoredFilter, X: traits::FlavoredFilter, Y: traits::FlavoredFilter,
58{
59 fn filter<C, R>(&self, conn: &C) -> Result<String>
60 where C: traits::Connection<R>, R: traits::Row,
61 {
62 let a = self.t.filter(conn)?; let b = self.u.filter(conn)?;
63 let r = match self.v.as_ref().map(|v| v.filter(conn)).transpose()? {
64 Some(c) => match self.w.as_ref().map(|w| w.filter(conn)).transpose()? {
65 Some(d) => match self.x.as_ref().map(|x| x.filter(conn)).transpose()? {
66 Some(e) => match self.y.as_ref().map(|y| y.filter(conn)).transpose()? {
67 Some(f) => format!("( {a} AND {b} AND {c} AND {d} AND {e} AND {f} )"),
68 None => format!("( {a} AND {b} AND {c} AND {d} AND {e} )"),
69 },
70 None => format!("( {a} AND {b} AND {c} AND {d} )"),
71 },
72 None => format!("( {a} AND {b} AND {c} )"),
73 },
74 None => format!("( {a} AND {b} )"),
75 };
76 Ok(r)
77 }
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83
84 struct WordOne { }
85 impl traits::FlavoredFilter for WordOne {
86 fn filter<C, R>(&self, _: &C) -> Result<String>
87 where C: traits::Connection<R>, R: traits::Row,
88 {
89 Ok("1".to_string())
90 }
91 }
92
93 struct WordHouse { }
94 impl traits::FlavoredFilter for WordHouse {
95 fn filter<C, R>(&self, _: &C) -> Result<String>
96 where C: traits::Connection<R>, R: traits::Row,
97 {
98 Ok("House".to_string())
99 }
100 }
101
102 #[cfg(test)]
103 fn it_combines_filter() -> Result<()> {
104 use traits::FlavoredFilter;
105 let conn = traits::tests::SQLiteFlavoredConnection {};
106 type Row = traits::tests::Row;
107
108 let and: And<_, _, _, _, _, _> = (WordOne {}, WordOne {}).into();
109 assert!(and.filter::<_, Row>(&conn)?.eq("( 1 AND 1 )"));
110
111 let and: And<_, _, _, _, _, _> = (WordOne {}, WordHouse {}, WordOne {}).into();
112 assert!(and.filter::<_, Row>(&conn)?.eq("( 1 AND House AND 1 )"));
113
114 let and: And<_, _, _, _, _, _> = (WordOne {}, WordHouse {}, WordHouse {}, WordOne {}).into();
115 assert!(and.filter::<_, Row>(&conn)?.eq("( 1 AND House AND House AND 1 )"));
116
117 let and: And<_, _, _, _, _, _> = (WordOne {}, WordHouse {}, WordHouse {}, WordOne {}, WordHouse {}, ).into();
118 assert!(and.filter::<_, Row>(&conn)?.eq("( 1 AND House AND House AND 1 AND House )"));
119
120 let and: And<_, _, _, _, _, _> = (WordOne {}, WordHouse {}, WordHouse {}, WordOne {}, WordHouse {}, WordHouse {}).into();
121 assert!(and.filter::<_, Row>(&conn)?.eq("( 1 AND House AND House AND 1 AND House AND House )"));
122
123 Ok(())
124 }
125}