diesel_softdelete/
methods.rs

1//! Expression methods implemented on the table.
2
3use diesel::{
4    dsl::{not, Filter, Find},
5    helper_types::not as Not,
6    query_dsl::methods::{FilterDsl, FindDsl},
7};
8
9use super::SoftDelete;
10
11pub trait SoftDeleteDsl: SoftDelete {
12    /// The type returned by `.soft_deleted`.
13    type Output;
14    fn soft_deleted(self) -> Self::Output;
15}
16
17pub type SoftDeleted<Source> = Filter<Source, Not<<Source as SoftDelete>::Deleted>>;
18
19impl<T> SoftDeleteDsl for T
20where
21    Self: SoftDelete + FilterDsl<Not<Self::Deleted>>,
22{
23    type Output = SoftDeleted<Self>;
24    fn soft_deleted(self) -> Self::Output {
25        let deleted = self.deleted_col();
26        self.filter(not(deleted))
27    }
28}
29
30pub type SoftFind<Source, PK> = Filter<Find<Source, PK>, Not<<Source as SoftDelete>::Deleted>>;
31
32/// The `soft_find` method
33pub trait SoftFindDsl<PK>: SoftDelete {
34    /// The type returned by `.soft_find`.
35    type Output;
36    fn soft_find(self, id: PK) -> Self::Output;
37}
38
39impl<T, PK> SoftFindDsl<PK> for T
40where
41    Self: SoftDelete + FindDsl<PK>,
42    Find<Self, PK>: FilterDsl<Not<Self::Deleted>>,
43{
44    type Output = SoftFind<Self, PK>;
45
46    fn soft_find(self, id: PK) -> Self::Output {
47        let deleted = self.deleted_col();
48        self.find(id).filter(not(deleted))
49    }
50}
51
52pub type SoftFilter<Source, Predicate> =
53    Filter<Filter<Source, Predicate>, Not<<Source as SoftDelete>::Deleted>>;
54
55/// The `soft_filter` method.
56///
57/// This trait is used to automatically add soft-delete filtering on regular `filter` in queries.
58/// It only needs to be put once per query.
59///
60/// Be careful with it, as it is often incorrect to use it on left-joined tables. For such cases,
61/// use the [`soft_left_join`](crate::query_dsl::SoftJoinDsl::soft_left_join) method to join the
62/// table and don't filter on the deleted status.
63pub trait SoftFilterDsl<Predicate>: SoftDelete {
64    /// The type returned by `.soft_filter`.
65    type Output;
66    fn soft_filter(self, predicate: Predicate) -> Self::Output;
67}
68
69impl<T, Predicate> SoftFilterDsl<Predicate> for T
70where
71    Self: SoftDelete + FilterDsl<Predicate>,
72    Filter<Self, Predicate>: FilterDsl<Not<Self::Deleted>>,
73{
74    type Output = SoftFilter<Self, Predicate>;
75
76    fn soft_filter(self, predicate: Predicate) -> Self::Output {
77        let deleted = self.deleted_col();
78        self.filter(predicate).filter(not(deleted))
79    }
80}