1use crate::SqlClause;
2use std::marker::PhantomData;
3use tokio_postgres::types::ToSql;
4
5#[derive(Debug, Clone)]
6pub struct Clause<'q, T> {
7 pub(crate) sql: String,
8 pub(crate) params: Vec<&'q (dyn ToSql + Sync)>,
9 _ph: PhantomData<T>,
10}
11impl<'q, T> Clause<'q, T> {
12 pub(crate) fn new(sql: String, params: Vec<&'q (dyn ToSql + Sync)>) -> Self {
13 Self {
14 sql,
15 params,
16 _ph: PhantomData,
17 }
18 }
19 pub fn build(self) -> (String, Vec<&'q (dyn ToSql + Sync)>) {
25 let init_capacity = self.sql.len() + self.params.len();
26 let mut result = String::with_capacity(init_capacity);
27 let mut start = 0;
28 let mut count = 1;
29 for (i, _) in self.sql.match_indices("$") {
30 result.push_str(&self.sql[start..i]);
31 result.push_str(&format!("${count}"));
32 count += 1;
33 start = i + 1;
34 }
35 result.push_str(&self.sql[start..]);
36 (result, self.params)
37 }
38 pub fn this(self) -> Self {
39 self
40 }
41
42 pub fn into<C>(self) -> Clause<'q, C> {
43 Clause::new(self.sql, self.params)
44 }
45 pub fn combine_raw(self, raw_sql: &str, params: &[&'q (dyn ToSql + Sync)]) -> Self {
46 let (mut s, mut p) = self.unwrap();
47 s.push(' ');
48 s.push_str(&raw_sql.trim());
49 p.extend_from_slice(params);
50 Self::new(s, p)
51 }
52}