toasty_core/stmt/
expr_set.rs

1use std::fmt;
2
3use super::{Expr, ExprSetOp, Insert, Select, SourceModel, Update, Values};
4use crate::schema::db::TableId;
5
6/// A set of rows produced by a query, set operation, or explicit values.
7///
8/// Represents the different ways to produce a collection of rows in SQL.
9///
10/// # Examples
11///
12/// ```text
13/// SELECT * FROM users           // ExprSet::Select
14/// SELECT ... UNION SELECT ...   // ExprSet::SetOp
15/// VALUES (1, 'a'), (2, 'b')     // ExprSet::Values
16/// ```
17#[derive(Clone, PartialEq)]
18pub enum ExprSet {
19    /// A select query, possibly with a filter.
20    Select(Box<Select>),
21
22    /// A set operation (union, intersection, ...) on two queries.
23    SetOp(ExprSetOp),
24
25    /// An update expression.
26    Update(Box<Update>),
27
28    /// Explicitly listed values (as expressions).
29    Values(Values),
30
31    /// An insert statement (used for UNION-style batch inserts)
32    Insert(Box<Insert>),
33}
34
35impl ExprSet {
36    pub fn values(values: impl Into<Values>) -> ExprSet {
37        ExprSet::Values(values.into())
38    }
39
40    /// Returns `true` if this is an [`ExprSet::Values`] variant.
41    ///
42    /// # Examples
43    ///
44    /// ```
45    /// # use toasty_core::stmt::{ExprSet, Values};
46    /// let values = ExprSet::values(Values::default());
47    /// assert!(values.is_values());
48    ///
49    /// let select = ExprSet::from(toasty_core::schema::db::TableId(0));
50    /// assert!(!select.is_values());
51    /// ```
52    pub fn is_values(&self) -> bool {
53        matches!(self, ExprSet::Values(_))
54    }
55
56    /// Returns a reference to the inner [`Values`] if this is an [`ExprSet::Values`].
57    ///
58    /// Returns `None` for all other [`ExprSet`] variants.
59    #[track_caller]
60    pub fn as_values(&self) -> Option<&Values> {
61        match self {
62            Self::Values(values) => Some(values),
63            _ => None,
64        }
65    }
66
67    /// Returns a reference to the inner [`Values`].
68    ///
69    /// # Panics
70    ///
71    /// Panics if `self` is not an [`ExprSet::Values`].
72    #[track_caller]
73    pub fn as_values_unwrap(&self) -> &Values {
74        match self {
75            Self::Values(values) => values,
76            v => panic!("expected `Values`, found {v:#?}"),
77        }
78    }
79
80    #[track_caller]
81    pub fn as_values_mut(&mut self) -> &mut Values {
82        match self {
83            Self::Values(expr) => expr,
84            _ => todo!(),
85        }
86    }
87
88    #[track_caller]
89    pub fn into_values(self) -> Values {
90        match self {
91            Self::Values(expr) => expr,
92            _ => todo!(),
93        }
94    }
95
96    pub fn is_const(&self) -> bool {
97        match self {
98            ExprSet::Select(..) => false,
99            ExprSet::SetOp(expr_set_op) => expr_set_op
100                .operands
101                .iter()
102                .all(|operand| operand.is_const()),
103            ExprSet::Update(..) => false,
104            ExprSet::Values(values) => values.is_const(),
105            ExprSet::Insert(..) => false,
106        }
107    }
108}
109
110impl fmt::Debug for ExprSet {
111    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
112        match self {
113            Self::Select(e) => e.fmt(f),
114            Self::SetOp(e) => e.fmt(f),
115            Self::Update(e) => e.fmt(f),
116            Self::Values(e) => e.fmt(f),
117            Self::Insert(e) => e.fmt(f),
118        }
119    }
120}
121
122impl Default for ExprSet {
123    fn default() -> Self {
124        Self::Values(Values::default())
125    }
126}
127
128impl From<Select> for ExprSet {
129    fn from(value: Select) -> Self {
130        Self::Select(Box::new(value))
131    }
132}
133
134impl From<Update> for ExprSet {
135    fn from(value: Update) -> Self {
136        Self::Update(Box::new(value))
137    }
138}
139
140impl From<Insert> for ExprSet {
141    fn from(value: Insert) -> Self {
142        Self::Insert(Box::new(value))
143    }
144}
145
146impl From<TableId> for ExprSet {
147    fn from(value: TableId) -> Self {
148        Self::Select(Box::new(Select::from(value)))
149    }
150}
151
152impl From<SourceModel> for ExprSet {
153    fn from(value: SourceModel) -> Self {
154        Self::Select(Box::new(Select::from(value)))
155    }
156}
157
158impl From<Vec<Expr>> for ExprSet {
159    fn from(value: Vec<Expr>) -> Self {
160        Self::Values(Values::new(value))
161    }
162}