toasty_driver_integration_suite/tests/
embed_enum_string_discriminant.rs1use crate::prelude::*;
2
3#[driver_test(id(ID))]
5pub async fn string_discriminant_unit_enum(t: &mut Test) -> Result<()> {
6 #[derive(Debug, PartialEq, toasty::Embed)]
7 enum Status {
8 #[column(variant = "pending")]
9 Pending,
10 #[column(variant = "active")]
11 Active,
12 #[column(variant = "done")]
13 Done,
14 }
15
16 #[derive(Debug, toasty::Model)]
17 struct Task {
18 #[key]
19 #[auto]
20 id: ID,
21 title: String,
22 status: Status,
23 }
24
25 let mut db = t.setup_db(models!(Task, Status)).await;
26
27 let task = toasty::create!(Task {
28 title: "Ship it",
29 status: Status::Pending,
30 })
31 .exec(&mut db)
32 .await?;
33 assert_eq!(task.status, Status::Pending);
34
35 let found = Task::get_by_id(&mut db, &task.id).await?;
36 assert_eq!(found.status, Status::Pending);
37
38 let mut task = found;
40 task.update().status(Status::Active).exec(&mut db).await?;
41 let found = Task::get_by_id(&mut db, &task.id).await?;
42 assert_eq!(found.status, Status::Active);
43
44 Ok(())
45}
46
47#[driver_test(id(ID))]
49pub async fn default_string_labels(t: &mut Test) -> Result<()> {
50 #[derive(Debug, PartialEq, toasty::Embed)]
51 enum Priority {
52 Low,
53 Medium,
54 High,
55 }
56
57 #[derive(Debug, toasty::Model)]
58 struct Task {
59 #[key]
60 #[auto]
61 id: ID,
62 title: String,
63 priority: Priority,
64 }
65
66 let mut db = t.setup_db(models!(Task, Priority)).await;
67
68 let task = toasty::create!(Task {
69 title: "Fix bug",
70 priority: Priority::High,
71 })
72 .exec(&mut db)
73 .await?;
74 assert_eq!(task.priority, Priority::High);
75
76 let found = Task::get_by_id(&mut db, &task.id).await?;
77 assert_eq!(found.priority, Priority::High);
78
79 Ok(())
80}
81
82#[driver_test(id(ID))]
84pub async fn mixed_explicit_and_default_labels(t: &mut Test) -> Result<()> {
85 #[derive(Debug, PartialEq, toasty::Embed)]
86 enum Status {
87 #[column(variant = "waiting")]
88 Pending,
89 Active,
90 Done,
91 }
92
93 #[derive(Debug, toasty::Model)]
94 struct Task {
95 #[key]
96 #[auto]
97 id: ID,
98 status: Status,
99 }
100
101 let mut db = t.setup_db(models!(Task, Status)).await;
102
103 let t1 = toasty::create!(Task {
105 status: Status::Pending
106 })
107 .exec(&mut db)
108 .await?;
109 assert_eq!(t1.status, Status::Pending);
110
111 let t2 = toasty::create!(Task {
113 status: Status::Active
114 })
115 .exec(&mut db)
116 .await?;
117
118 let found1 = Task::get_by_id(&mut db, &t1.id).await?;
119 let found2 = Task::get_by_id(&mut db, &t2.id).await?;
120 assert_eq!(found1.status, Status::Pending);
121 assert_eq!(found2.status, Status::Active);
122
123 Ok(())
124}
125
126#[driver_test(id(ID))]
128pub async fn string_discriminant_data_enum(t: &mut Test) -> Result<()> {
129 #[derive(Debug, PartialEq, toasty::Embed)]
130 enum ContactMethod {
131 #[column(variant = "email")]
132 Email { address: String },
133 #[column(variant = "phone")]
134 Phone { number: String },
135 }
136
137 #[derive(Debug, toasty::Model)]
138 #[allow(dead_code)]
139 struct User {
140 #[key]
141 #[auto]
142 id: ID,
143 name: String,
144 contact: ContactMethod,
145 }
146
147 let mut db = t.setup_db(models!(User, ContactMethod)).await;
148
149 let user = toasty::create!(User {
150 name: "Alice",
151 contact: ContactMethod::Email {
152 address: "alice@example.com".into(),
153 },
154 })
155 .exec(&mut db)
156 .await?;
157
158 let found = User::get_by_id(&mut db, &user.id).await?;
159 assert_eq!(
160 found.contact,
161 ContactMethod::Email {
162 address: "alice@example.com".into()
163 }
164 );
165
166 let mut user = found;
168 user.update()
169 .contact(ContactMethod::Phone {
170 number: "555-0100".into(),
171 })
172 .exec(&mut db)
173 .await?;
174
175 let found = User::get_by_id(&mut db, &user.id).await?;
176 assert_eq!(
177 found.contact,
178 ContactMethod::Phone {
179 number: "555-0100".into()
180 }
181 );
182
183 Ok(())
184}
185
186#[driver_test(id(ID))]
188pub async fn default_string_labels_data_enum(t: &mut Test) -> Result<()> {
189 #[derive(Debug, PartialEq, toasty::Embed)]
190 enum ContactMethod {
191 Email { address: String },
192 Phone { number: String },
193 }
194
195 #[derive(Debug, toasty::Model)]
196 #[allow(dead_code)]
197 struct User {
198 #[key]
199 #[auto]
200 id: ID,
201 name: String,
202 contact: ContactMethod,
203 }
204
205 let mut db = t.setup_db(models!(User, ContactMethod)).await;
206
207 let user = toasty::create!(User {
208 name: "Alice",
209 contact: ContactMethod::Email {
210 address: "alice@example.com".into(),
211 },
212 })
213 .exec(&mut db)
214 .await?;
215
216 let found = User::get_by_id(&mut db, &user.id).await?;
217 assert_eq!(
218 found.contact,
219 ContactMethod::Email {
220 address: "alice@example.com".into()
221 }
222 );
223
224 let mut user = found;
226 user.update()
227 .contact(ContactMethod::Phone {
228 number: "555-0100".into(),
229 })
230 .exec(&mut db)
231 .await?;
232
233 let found = User::get_by_id(&mut db, &user.id).await?;
234 assert_eq!(
235 found.contact,
236 ContactMethod::Phone {
237 number: "555-0100".into()
238 }
239 );
240
241 Ok(())
242}
243
244#[driver_test(id(ID))]
246pub async fn mixed_string_labels_data_enum(t: &mut Test) -> Result<()> {
247 #[derive(Debug, PartialEq, toasty::Embed)]
248 enum ContactMethod {
249 #[column(variant = "mail")]
250 Email {
251 address: String,
252 },
253 Phone {
254 number: String,
255 },
256 }
257
258 #[derive(Debug, toasty::Model)]
259 #[allow(dead_code)]
260 struct User {
261 #[key]
262 #[auto]
263 id: ID,
264 name: String,
265 contact: ContactMethod,
266 }
267
268 let mut db = t.setup_db(models!(User, ContactMethod)).await;
269
270 let u1 = toasty::create!(User {
272 name: "Alice",
273 contact: ContactMethod::Email {
274 address: "alice@example.com".into(),
275 },
276 })
277 .exec(&mut db)
278 .await?;
279
280 let u2 = toasty::create!(User {
282 name: "Bob",
283 contact: ContactMethod::Phone {
284 number: "555-0200".into(),
285 },
286 })
287 .exec(&mut db)
288 .await?;
289
290 let found1 = User::get_by_id(&mut db, &u1.id).await?;
291 assert_eq!(
292 found1.contact,
293 ContactMethod::Email {
294 address: "alice@example.com".into()
295 }
296 );
297
298 let found2 = User::get_by_id(&mut db, &u2.id).await?;
299 assert_eq!(
300 found2.contact,
301 ContactMethod::Phone {
302 number: "555-0200".into()
303 }
304 );
305
306 let mut user = found1;
308 user.update()
309 .contact(ContactMethod::Phone {
310 number: "555-0300".into(),
311 })
312 .exec(&mut db)
313 .await?;
314
315 let found = User::get_by_id(&mut db, &user.id).await?;
316 assert_eq!(
317 found.contact,
318 ContactMethod::Phone {
319 number: "555-0300".into()
320 }
321 );
322
323 Ok(())
324}
325
326#[driver_test(requires(sql))]
328pub async fn filter_by_string_variant(t: &mut Test) -> Result<()> {
329 #[derive(Debug, PartialEq, toasty::Embed)]
330 enum Status {
331 #[column(variant = "pending")]
332 Pending,
333 #[column(variant = "active")]
334 Active,
335 }
336
337 #[derive(Debug, toasty::Model)]
338 #[allow(dead_code)]
339 struct Task {
340 #[key]
341 #[auto]
342 id: uuid::Uuid,
343 title: String,
344 status: Status,
345 }
346
347 let mut db = t.setup_db(models!(Task, Status)).await;
348
349 toasty::create!(Task {
350 title: "A",
351 status: Status::Pending
352 })
353 .exec(&mut db)
354 .await?;
355
356 toasty::create!(Task {
357 title: "B",
358 status: Status::Active
359 })
360 .exec(&mut db)
361 .await?;
362
363 let pending = Task::filter(Task::fields().status().is_pending())
364 .exec(&mut db)
365 .await?;
366 assert_eq!(pending.len(), 1);
367 assert_eq!(pending[0].title, "A");
368
369 Ok(())
370}
371
372#[driver_test]
374pub async fn string_discriminant_schema_registration(t: &mut Test) {
375 #[derive(Debug, PartialEq, toasty::Embed)]
376 enum Color {
377 #[column(variant = "red")]
378 Red,
379 #[column(variant = "green")]
380 Green,
381 #[column(variant = "blue")]
382 Blue,
383 }
384
385 let db = t.setup_db(models!(Color)).await;
386 let schema = db.schema();
387
388 let color_model = schema.app.model(Color::id()).as_embedded_enum_unwrap();
389 assert_eq!(color_model.discriminant.ty, toasty_core::stmt::Type::String);
390 assert_eq!(color_model.variants.len(), 3);
391 assert_eq!(
392 color_model.variants[0].discriminant,
393 toasty_core::stmt::Value::String("red".to_string())
394 );
395 assert_eq!(
396 color_model.variants[1].discriminant,
397 toasty_core::stmt::Value::String("green".to_string())
398 );
399 assert_eq!(
400 color_model.variants[2].discriminant,
401 toasty_core::stmt::Value::String("blue".to_string())
402 );
403}