1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
use super::predicate::{And, Eq, Op, Predicate};
use crate::types::Primative;
use crate::{Table, ToSql};
use std::marker::PhantomData;

pub trait UpdateSet {
    fn write_set(&self, sql: &mut String);
}

impl<T, A, U> UpdateSet for Op<T, A, U, Eq>
where
    T: Table,
    U: Primative,
{
    fn write_set(&self, sql: &mut String) {
        self.write_predicate(sql);
    }
}

impl<H, T> UpdateSet for And<H, T>
where
    H: UpdateSet,
    T: UpdateSet,
{
    fn write_set(&self, sql: &mut String) {
        self.head.write_set(sql);
        sql.push(',');
        self.tail.write_set(sql);
    }
}

pub struct Update<T: ?Sized, S> {
    _table: PhantomData<T>,
    set: S,
}

impl<T: ?Sized, S> Update<T, S> {
    pub(crate) const fn new(set: S) -> Self {
        Self {
            _table: PhantomData,
            set,
        }
    }
}

impl<T, S> ToSql for Update<T, S>
where
    T: Table + ?Sized,
    S: UpdateSet,
{
    fn write_sql(&self, sql: &mut String) {
        sql.push_str("UPDATE ");
        sql.push_str(T::NAME);
        sql.push_str(" SET ");
        self.set.write_set(sql);
    }
}