1use super::{Field, FieldId, FieldPrimitive, Index, Name, PrimaryKey};
2use crate::{driver, stmt, Result};
3use std::fmt;
4
5#[derive(Debug, Clone)]
6pub enum Model {
7 Root(ModelRoot),
9 EmbeddedStruct(EmbeddedStruct),
11 EmbeddedEnum(EmbeddedEnum),
13}
14
15#[derive(Debug, Clone)]
16pub struct ModelRoot {
17 pub id: ModelId,
19
20 pub name: Name,
22
23 pub fields: Vec<Field>,
25
26 pub primary_key: PrimaryKey,
28
29 pub table_name: Option<String>,
31
32 pub indices: Vec<Index>,
34}
35
36impl ModelRoot {
37 pub fn find_by_id(&self, mut input: impl stmt::Input) -> stmt::Query {
38 let filter = match &self.primary_key.fields[..] {
39 [pk_field] => stmt::Expr::eq(
40 stmt::Expr::ref_self_field(pk_field),
41 input
42 .resolve_arg(&0.into(), &stmt::Projection::identity())
43 .unwrap(),
44 ),
45 pk_fields => stmt::Expr::and_from_vec(
46 pk_fields
47 .iter()
48 .enumerate()
49 .map(|(i, pk_field)| {
50 stmt::Expr::eq(
51 stmt::Expr::ref_self_field(pk_field),
52 input
53 .resolve_arg(&i.into(), &stmt::Projection::identity())
54 .unwrap(),
55 )
56 })
57 .collect(),
58 ),
59 };
60
61 stmt::Query::new_select(self.id, filter)
62 }
63
64 pub fn primary_key_fields(&self) -> impl ExactSizeIterator<Item = &'_ Field> {
66 self.primary_key
67 .fields
68 .iter()
69 .map(|pk_field| &self.fields[pk_field.index])
70 }
71
72 pub fn field_by_name(&self, name: &str) -> Option<&Field> {
73 self.fields.iter().find(|field| field.name.app_name == name)
74 }
75
76 pub(crate) fn verify(&self, db: &driver::Capability) -> Result<()> {
77 for field in &self.fields {
78 field.verify(db)?;
79 }
80 Ok(())
81 }
82}
83
84#[derive(Debug, Clone)]
85pub struct EmbeddedStruct {
86 pub id: ModelId,
88
89 pub name: Name,
91
92 pub fields: Vec<Field>,
94
95 pub indices: Vec<Index>,
101}
102
103impl EmbeddedStruct {
104 pub(crate) fn verify(&self, db: &driver::Capability) -> Result<()> {
105 for field in &self.fields {
106 field.verify(db)?;
107 }
108 Ok(())
109 }
110}
111
112#[derive(Debug, Clone)]
113pub struct EmbeddedEnum {
114 pub id: ModelId,
116
117 pub name: Name,
119
120 pub discriminant: FieldPrimitive,
122
123 pub variants: Vec<EnumVariant>,
125
126 pub fields: Vec<Field>,
129
130 pub indices: Vec<Index>,
136}
137
138#[derive(Debug, Clone)]
139pub struct EnumVariant {
140 pub name: Name,
142
143 pub discriminant: i64,
145}
146
147impl EmbeddedEnum {
148 pub fn has_data_variants(&self) -> bool {
150 !self.fields.is_empty()
151 }
152
153 pub fn variant_fields(&self, variant_index: usize) -> impl Iterator<Item = &Field> {
155 let variant_id = VariantId {
156 model: self.id,
157 index: variant_index,
158 };
159 self.fields
160 .iter()
161 .filter(move |f| f.variant == Some(variant_id))
162 }
163
164 pub(crate) fn verify(&self, db: &driver::Capability) -> Result<()> {
165 for field in &self.fields {
166 field.verify(db)?;
167 }
168 Ok(())
169 }
170}
171
172#[derive(Copy, Clone, Eq, PartialEq, Hash)]
173#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
174pub struct ModelId(pub usize);
175
176impl Model {
177 pub fn id(&self) -> ModelId {
178 match self {
179 Model::Root(root) => root.id,
180 Model::EmbeddedStruct(embedded) => embedded.id,
181 Model::EmbeddedEnum(e) => e.id,
182 }
183 }
184
185 pub fn name(&self) -> &Name {
186 match self {
187 Model::Root(root) => &root.name,
188 Model::EmbeddedStruct(embedded) => &embedded.name,
189 Model::EmbeddedEnum(e) => &e.name,
190 }
191 }
192
193 pub fn is_root(&self) -> bool {
195 matches!(self, Model::Root(_))
196 }
197
198 pub fn is_embedded(&self) -> bool {
200 matches!(self, Model::EmbeddedStruct(_) | Model::EmbeddedEnum(_))
201 }
202
203 pub fn can_be_relation_target(&self) -> bool {
205 self.is_root()
206 }
207
208 pub fn as_root(&self) -> Option<&ModelRoot> {
209 match self {
210 Model::Root(root) => Some(root),
211 _ => None,
212 }
213 }
214
215 pub fn expect_root(&self) -> &ModelRoot {
217 match self {
218 Model::Root(root) => root,
219 Model::EmbeddedStruct(_) => panic!("expected root model, found embedded struct"),
220 Model::EmbeddedEnum(_) => panic!("expected root model, found embedded enum"),
221 }
222 }
223
224 pub fn expect_root_mut(&mut self) -> &mut ModelRoot {
226 match self {
227 Model::Root(root) => root,
228 Model::EmbeddedStruct(_) => panic!("expected root model, found embedded struct"),
229 Model::EmbeddedEnum(_) => panic!("expected root model, found embedded enum"),
230 }
231 }
232
233 pub fn expect_embedded_struct(&self) -> &EmbeddedStruct {
235 match self {
236 Model::EmbeddedStruct(embedded) => embedded,
237 Model::Root(_) => panic!("expected embedded struct, found root model"),
238 Model::EmbeddedEnum(_) => panic!("expected embedded struct, found embedded enum"),
239 }
240 }
241
242 pub fn expect_embedded_enum(&self) -> &EmbeddedEnum {
244 match self {
245 Model::EmbeddedEnum(e) => e,
246 Model::Root(_) => panic!("expected embedded enum, found root model"),
247 Model::EmbeddedStruct(_) => panic!("expected embedded enum, found embedded struct"),
248 }
249 }
250
251 pub(crate) fn verify(&self, db: &driver::Capability) -> Result<()> {
252 match self {
253 Model::Root(root) => root.verify(db),
254 Model::EmbeddedStruct(embedded) => embedded.verify(db),
255 Model::EmbeddedEnum(e) => e.verify(db),
256 }
257 }
258}
259
260#[derive(Copy, Clone, PartialEq, Eq, Hash)]
262pub struct VariantId {
263 pub model: ModelId,
265 pub index: usize,
267}
268
269impl fmt::Debug for VariantId {
270 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
271 write!(fmt, "VariantId({}/{})", self.model.0, self.index)
272 }
273}
274
275impl ModelId {
276 pub const fn field(self, index: usize) -> FieldId {
279 FieldId { model: self, index }
280 }
281
282 pub const fn variant(self, index: usize) -> VariantId {
285 VariantId { model: self, index }
286 }
287
288 pub(crate) const fn placeholder() -> Self {
289 Self(usize::MAX)
290 }
291}
292
293impl From<&Self> for ModelId {
294 fn from(src: &Self) -> Self {
295 *src
296 }
297}
298
299impl From<&mut Self> for ModelId {
300 fn from(src: &mut Self) -> Self {
301 *src
302 }
303}
304
305impl From<&Model> for ModelId {
306 fn from(value: &Model) -> Self {
307 value.id()
308 }
309}
310
311impl From<&ModelRoot> for ModelId {
312 fn from(value: &ModelRoot) -> Self {
313 value.id
314 }
315}
316
317impl fmt::Debug for ModelId {
318 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
319 write!(fmt, "ModelId({})", self.0)
320 }
321}