diesel/query_builder/upsert/
on_conflict_target_decorations.rs

1use crate::backend::Backend;
2use crate::expression::Expression;
3use crate::query_builder::upsert::on_conflict_target::{ConflictTarget, NoConflictTarget};
4use crate::query_builder::where_clause::{NoWhereClause, WhereAnd, WhereClause};
5use crate::query_builder::{AstPass, QueryFragment, QueryResult};
6use crate::sql_types::BoolOrNullableBool;
7
8pub trait UndecoratedConflictTarget {}
9
10impl UndecoratedConflictTarget for NoConflictTarget {}
11impl<T> UndecoratedConflictTarget for ConflictTarget<T> {}
12
13/// Interface to add information to conflict targets.
14/// Designed to be open for further additions to conflict targets like constraints
15pub trait DecoratableTarget<P> {
16    /// Output type of filter_target operation
17    type FilterOutput;
18    /// equivalent to filter of FilterDsl but aimed at conflict targets
19    fn filter_target(self, predicate: P) -> Self::FilterOutput;
20}
21
22#[derive(Debug)]
23pub struct DecoratedConflictTarget<T, U> {
24    pub(crate) target: T,
25    pub(crate) where_clause: U,
26}
27
28impl<T, P> DecoratableTarget<P> for T
29where
30    P: Expression,
31    P::SqlType: BoolOrNullableBool,
32    T: UndecoratedConflictTarget,
33{
34    type FilterOutput = DecoratedConflictTarget<T, WhereClause<P>>;
35
36    fn filter_target(self, predicate: P) -> Self::FilterOutput {
37        DecoratedConflictTarget {
38            target: self,
39            where_clause: NoWhereClause.and(predicate),
40        }
41    }
42}
43
44impl<T, U, P> DecoratableTarget<P> for DecoratedConflictTarget<T, U>
45where
46    P: Expression,
47    P::SqlType: BoolOrNullableBool,
48    U: WhereAnd<P>,
49{
50    type FilterOutput = DecoratedConflictTarget<T, <U as WhereAnd<P>>::Output>;
51
52    fn filter_target(self, predicate: P) -> Self::FilterOutput {
53        DecoratedConflictTarget {
54            target: self.target,
55            where_clause: self.where_clause.and(predicate),
56        }
57    }
58}
59
60impl<DB, T, U> QueryFragment<DB> for DecoratedConflictTarget<T, U>
61where
62    DB: Backend,
63    Self: QueryFragment<DB, DB::OnConflictClause>,
64{
65    fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
66        <Self as QueryFragment<DB, DB::OnConflictClause>>::walk_ast(self, pass)
67    }
68}