typed_sql/query/
predicate.rs1use 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> {}