Skip to main content

toasty_core/stmt/
delete.rs

1use super::{Condition, Node, Query, Returning, Source, Statement, Visit, VisitMut};
2use crate::stmt::{self, Filter};
3
4/// A `DELETE` statement that removes existing records.
5///
6/// Specifies a source to delete from, a filter selecting which records to
7/// delete, and an optional returning clause.
8///
9/// # Examples
10///
11/// ```ignore
12/// use toasty_core::stmt::{Delete, Source, Filter};
13/// use toasty_core::schema::app::ModelId;
14///
15/// let delete = Delete {
16///     from: Source::from(ModelId(0)),
17///     filter: Filter::default(),
18///     returning: None,
19/// };
20/// ```
21#[derive(Debug, Clone, PartialEq)]
22pub struct Delete {
23    /// The source to delete from (`FROM` clause).
24    pub from: Source,
25
26    /// Filter selecting which records to delete (`WHERE` clause).
27    pub filter: Filter,
28
29    /// Optional `RETURNING` clause.
30    pub returning: Option<Returning>,
31
32    /// An optional condition that must hold for the delete to apply.
33    /// Unlike `filter`, a failing condition surfaces as an error rather than
34    /// silently skipping the record.
35    pub condition: Condition,
36}
37
38impl Delete {
39    /// Returns a [`Query`] that selects the records this delete would remove.
40    pub fn selection(&self) -> Query {
41        stmt::Query::new_select(self.from.model_id_unwrap(), self.filter.clone())
42    }
43}
44
45impl Statement {
46    /// Returns `true` if this statement is a [`Delete`].
47    pub fn is_delete(&self) -> bool {
48        matches!(self, Statement::Delete(..))
49    }
50
51    /// Attempts to return a reference to an inner [`Delete`].
52    ///
53    /// * If `self` is a [`Statement::Delete`], a reference to the inner [`Delete`] is
54    ///   returned wrapped in [`Some`].
55    /// * Else, [`None`] is returned.
56    pub fn as_delete(&self) -> Option<&Delete> {
57        match self {
58            Self::Delete(delete) => Some(delete),
59            _ => None,
60        }
61    }
62
63    /// Consumes `self` and attempts to return the inner [`Delete`].
64    ///
65    /// * If `self` is a [`Statement::Delete`], inner [`Delete`] is returned wrapped in
66    ///   [`Some`].
67    /// * Else, [`None`] is returned.
68    pub fn into_delete(self) -> Option<Delete> {
69        match self {
70            Self::Delete(delete) => Some(delete),
71            _ => None,
72        }
73    }
74
75    /// Consumes `self` and returns the inner [`Delete`].
76    ///
77    /// # Panics
78    ///
79    /// If `self` is not a [`Statement::Delete`].
80    pub fn into_delete_unwrap(self) -> Delete {
81        match self {
82            Self::Delete(delete) => delete,
83            v => panic!("expected `Delete`, found {v:#?}"),
84        }
85    }
86}
87
88impl From<Delete> for Statement {
89    fn from(src: Delete) -> Self {
90        Self::Delete(src)
91    }
92}
93
94impl Node for Delete {
95    fn visit<V: Visit>(&self, mut visit: V) {
96        visit.visit_stmt_delete(self);
97    }
98
99    fn visit_mut<V: VisitMut>(&mut self, mut visit: V) {
100        visit.visit_stmt_delete_mut(self);
101    }
102}