toasty_core/stmt/
select.rs1use super::{Node, Path, Query, Returning, Source, SourceModel, Statement, Visit, VisitMut};
2use crate::{
3 schema::db::TableId,
4 stmt::{ExprSet, Filter},
5};
6
7#[derive(Debug, Clone, PartialEq)]
8pub struct Select {
9 pub returning: Returning,
11
12 pub source: Source,
16
17 pub filter: Filter,
19}
20
21impl Select {
22 pub fn new(source: impl Into<Source>, filter: impl Into<Filter>) -> Self {
23 Self {
24 returning: Returning::Model { include: vec![] },
25 source: source.into(),
26 filter: filter.into(),
27 }
28 }
29
30 pub(crate) fn include(&mut self, path: impl Into<Path>) {
31 match &mut self.returning {
32 Returning::Model { include } => include.push(path.into()),
33 _ => panic!("Expected Returning::Model for include operation"),
34 }
35 }
36
37 pub fn add_filter(&mut self, filter: impl Into<Filter>) {
38 self.filter.add_filter(filter);
39 }
40}
41
42impl Statement {
43 pub fn as_select(&self) -> Option<&Select> {
44 self.as_query().and_then(|query| query.body.as_select())
45 }
46
47 #[track_caller]
48 pub fn as_select_unwrap(&self) -> &Select {
49 match self {
50 Statement::Query(query) => match &query.body {
51 ExprSet::Select(select) => select,
52 _ => todo!("expected `Select`; actual={self:#?}"),
53 },
54 _ => todo!("expected `Select`; actual={self:#?}"),
55 }
56 }
57}
58
59impl Query {
60 pub fn into_select(self) -> Select {
61 self.body.into_select()
62 }
63}
64
65impl ExprSet {
66 pub fn as_select(&self) -> Option<&Select> {
67 match self {
68 Self::Select(expr) => Some(expr),
69 _ => None,
70 }
71 }
72
73 #[track_caller]
74 pub fn as_select_unwrap(&self) -> &Select {
75 self.as_select()
76 .unwrap_or_else(|| panic!("expected `Select`; actual={self:#?}"))
77 }
78
79 pub fn as_select_mut(&mut self) -> Option<&mut Select> {
80 match self {
81 Self::Select(expr) => Some(expr),
82 _ => None,
83 }
84 }
85
86 pub fn as_select_mut_unwrap(&mut self) -> &mut Select {
87 match self {
88 Self::Select(select) => select,
89 _ => panic!("expected `Select`; actual={self:#?}"),
90 }
91 }
92
93 #[track_caller]
94 pub fn into_select(self) -> Select {
95 match self {
96 Self::Select(expr) => *expr,
97 _ => todo!(),
98 }
99 }
100
101 pub fn is_select(&self) -> bool {
102 matches!(self, Self::Select(_))
103 }
104}
105
106impl From<Select> for Statement {
107 fn from(value: Select) -> Self {
108 Self::Query(value.into())
109 }
110}
111
112impl From<Select> for Query {
113 fn from(value: Select) -> Self {
114 Self::builder(value).build()
115 }
116}
117
118impl From<TableId> for Select {
119 fn from(value: TableId) -> Self {
120 Self::new(Source::table(value), true)
121 }
122}
123
124impl From<SourceModel> for Select {
125 fn from(value: SourceModel) -> Self {
126 Self::new(Source::Model(value), true)
127 }
128}
129
130impl Node for Select {
131 fn visit<V: Visit>(&self, mut visit: V) {
132 visit.visit_stmt_select(self);
133 }
134
135 fn visit_mut<V: VisitMut>(&mut self, mut visit: V) {
136 visit.visit_stmt_select_mut(self);
137 }
138}