format_sql_query/
predicates.rs1use itertools::Itertools;
2use std::fmt::{self, Display};
3
4pub struct PredicateStatement<'s> {
6 statement: &'static str,
7 predicates: &'s [Box<dyn Display>],
8}
9
10impl fmt::Display for PredicateStatement<'_> {
11 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12 write!(
13 f,
14 "{} {}",
15 self.statement,
16 self.predicates.iter().join("\nAND ")
17 )
18 }
19}
20
21pub struct Predicates(Vec<Box<dyn Display>>);
23
24impl IntoIterator for Predicates {
25 type Item = Box<dyn Display>;
26 type IntoIter = std::vec::IntoIter<Box<dyn Display>>;
27
28 fn into_iter(self) -> Self::IntoIter {
29 self.0.into_iter()
30 }
31}
32
33impl Predicates {
34 pub fn new() -> Predicates {
36 Predicates(Vec::new())
37 }
38
39 pub fn from<S: Display + 'static>(predicate: S) -> Predicates {
41 Predicates::new().and(predicate)
42 }
43
44 pub fn from_all<S, I, IT>(predicates: I) -> Self
46 where
47 S: Display + 'static,
48 I: IntoIterator<Item = S, IntoIter = IT>,
49 IT: Iterator<Item = S>,
50 {
51 Predicates::new().and_all(predicates)
52 }
53
54 pub fn as_where<'s>(&'s self) -> PredicateStatement<'s> {
56 PredicateStatement {
57 statement: "WHERE",
58 predicates: &self.0,
59 }
60 }
61
62 pub fn and_push<S: Display + 'static>(&mut self, predicate: S) {
64 self.and_extend(Some(predicate))
65 }
66
67 pub fn and_extend<S, I, IT>(&mut self, predicates: I) -> ()
69 where
70 S: Display + 'static,
71 I: IntoIterator<Item = S, IntoIter = IT>,
72 IT: Iterator<Item = S>,
73 {
74 self.0.extend(
75 predicates
76 .into_iter()
77 .map(|c| Box::new(c) as Box<dyn Display>),
78 );
79 }
80
81 pub fn and<S: Display + 'static>(mut self, predicate: S) -> Self {
83 self.and_push(predicate);
84 self
85 }
86
87 pub fn and_all<S, I, IT>(mut self, predicates: I) -> Self
89 where
90 S: Display + 'static,
91 I: IntoIterator<Item = S, IntoIter = IT>,
92 IT: Iterator<Item = S>,
93 {
94 self.and_extend(predicates);
95 self
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102
103 #[test]
104 fn it_works() {
105 assert_eq!(
106 Predicates::from("foo = 'bar'")
107 .and("baz")
108 .and_all(["hello", "world"].iter())
109 .and_all(Predicates::from_all(["abc", "123"].iter()))
110 .as_where()
111 .to_string(),
112 "WHERE foo = \'bar\'\nAND baz\nAND hello\nAND world\nAND abc\nAND 123"
113 );
114 }
115}