typed_sql/query/
predicate.rs

1use crate::types::Primitive;
2use crate::types::{Bind, Field};
3use crate::{CheckedSql, Table};
4use std::{fmt::Write, marker::PhantomData};
5
6pub trait Predicate {
7    fn write_predicate(&self, sql: &mut String);
8}
9
10pub struct And<H, T> {
11    pub(crate) head: H,
12    pub(crate) tail: T,
13}
14
15impl<H, T> Predicate for And<H, T>
16where
17    H: Predicate,
18    T: Predicate,
19{
20    fn write_predicate(&self, sql: &mut String) {
21        self.head.write_predicate(sql);
22        sql.push_str(" AND ");
23        self.tail.write_predicate(sql);
24    }
25}
26
27impl<H: CheckedSql, T: CheckedSql> CheckedSql for And<H, T> {}
28
29pub struct Or<H, T> {
30    pub(crate) head: H,
31    pub(crate) tail: T,
32}
33
34impl<H, T> Predicate for Or<H, T>
35where
36    H: Predicate,
37    T: Predicate,
38{
39    fn write_predicate(&self, sql: &mut String) {
40        self.head.write_predicate(sql);
41        sql.push_str(" OR ");
42        self.tail.write_predicate(sql);
43    }
44}
45
46impl<H: CheckedSql, T: CheckedSql> CheckedSql for Or<H, T> {}
47
48pub trait Operator {
49    fn write_operator(sql: &mut String);
50}
51
52pub struct Eq;
53
54impl Operator for Eq {
55    fn write_operator(sql: &mut String) {
56        sql.push('=');
57    }
58}
59
60pub struct Neq;
61
62impl Operator for Neq {
63    fn write_operator(sql: &mut String) {
64        sql.push_str("!=");
65    }
66}
67
68pub struct Gt;
69
70impl Operator for Gt {
71    fn write_operator(sql: &mut String) {
72        sql.push('>');
73    }
74}
75
76pub struct Lt;
77
78impl Operator for Lt {
79    fn write_operator(sql: &mut String) {
80        sql.push('<');
81    }
82}
83
84pub struct Op<T, A, U, O> {
85    lhs: Field<T, A>,
86    rhs: U,
87    _operator: PhantomData<O>,
88}
89
90impl<T, A, U, O> Op<T, A, U, O> {
91    pub(crate) fn new(lhs: Field<T, A>, rhs: U) -> Self {
92        Self {
93            lhs,
94            rhs,
95            _operator: PhantomData,
96        }
97    }
98}
99
100impl<T, A, U, O> Predicate for Op<T, A, U, O>
101where
102    T: Table,
103    U: Primitive,
104    O: Operator,
105{
106    fn write_predicate(&self, sql: &mut String) {
107        self.lhs.write_field(sql);
108        sql.push(' ');
109        O::write_operator(sql);
110        sql.push(' ');
111        self.rhs.write_primative(sql);
112    }
113}
114
115impl<T, T2, A, O> Predicate for Op<T, A, Field<T2, A>, O>
116where
117    T: Table,
118    T2: Table,
119    O: Operator,
120{
121    fn write_predicate(&self, sql: &mut String) {
122        self.lhs.write_field(sql);
123        sql.push(' ');
124        O::write_operator(sql);
125        sql.push(' ');
126        self.rhs.write_field(sql);
127    }
128}
129
130impl<T, A, O> Predicate for Op<T, A, Bind, O>
131where
132    T: Table,
133    O: Operator,
134{
135    fn write_predicate(&self, sql: &mut String) {
136        self.lhs.write_field(sql);
137        sql.push(' ');
138        O::write_operator(sql);
139        sql.write_fmt(format_args!(" ${}", self.rhs.n)).unwrap();
140    }
141}
142
143impl<T, A, U: CheckedSql, O> CheckedSql for Op<T, A, U, O> {}