Skip to main content

toasty_core/stmt/
condition.rs

1use crate::stmt::{Expr, Node, Statement, Visit, VisitMut};
2
3/// A guard condition on an [`Update`](super::Update) statement.
4///
5/// Unlike a [`Filter`](super::Filter), a condition does not select which rows
6/// to operate on. Instead, it is evaluated after the filter and determines
7/// whether the update should actually be applied. If the condition is not met,
8/// the update is silently skipped.
9///
10/// When `expr` is `None`, no condition is applied (the update always proceeds).
11///
12/// # Examples
13///
14/// ```
15/// use toasty_core::stmt::Condition;
16///
17/// let cond = Condition::default();
18/// assert!(cond.is_none());
19/// ```
20#[derive(Debug, Default, Clone, PartialEq)]
21pub struct Condition {
22    /// The condition expression, or `None` for unconditional updates.
23    pub expr: Option<Expr>,
24}
25
26impl Condition {
27    /// Creates a condition from an expression.
28    pub fn new(expr: impl Into<Expr>) -> Condition {
29        Condition {
30            expr: Some(expr.into()),
31        }
32    }
33
34    /// Returns `true` if a condition expression is set.
35    pub fn is_some(&self) -> bool {
36        self.expr.is_some()
37    }
38
39    /// Returns `true` if no condition expression is set.
40    pub fn is_none(&self) -> bool {
41        self.expr.is_none()
42    }
43}
44
45impl Statement {
46    /// Returns a reference to this statement's condition, if it has one and it
47    /// is set. Only `Update` and `Delete` statements support conditions.
48    pub fn condition(&self) -> Option<&Condition> {
49        match self {
50            Statement::Update(update) if update.condition.is_some() => Some(&update.condition),
51            Statement::Delete(delete) if delete.condition.is_some() => Some(&delete.condition),
52            _ => None,
53        }
54    }
55
56    /// Returns a mutable reference to the statement's condition.
57    ///
58    /// Returns `None` for statements that do not support conditions.
59    pub fn condition_mut(&mut self) -> Option<&mut Condition> {
60        match self {
61            Statement::Update(update) => Some(&mut update.condition),
62            Statement::Delete(delete) => Some(&mut delete.condition),
63            _ => None,
64        }
65    }
66
67    /// Returns a mutable reference to the statement's condition.
68    ///
69    /// # Panics
70    ///
71    /// Panics if the statement does not support conditions.
72    #[track_caller]
73    pub fn condition_mut_unwrap(&mut self) -> &mut Condition {
74        match self {
75            Statement::Update(update) => &mut update.condition,
76            Statement::Delete(delete) => &mut delete.condition,
77            _ => panic!("expected Statement with condition"),
78        }
79    }
80}
81
82impl Node for Condition {
83    fn visit<V: Visit>(&self, mut visit: V) {
84        visit.visit_condition(self);
85    }
86
87    fn visit_mut<V: VisitMut>(&mut self, mut visit: V) {
88        visit.visit_condition_mut(self);
89    }
90}
91
92impl<T> From<T> for Condition
93where
94    Expr: From<T>,
95{
96    fn from(value: T) -> Self {
97        Condition {
98            expr: Some(value.into()),
99        }
100    }
101}