1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize, Default)]
4pub struct DateQuery {
5 pub day: i32,
6 pub month: i32,
7 pub year: i32,
8 pub timezone: Option<f64>,
9 pub ruleset_id: Option<String>,
10 pub event_kind: Option<String>,
11 #[serde(default)]
12 pub enabled_pack_ids: Vec<String>,
13}
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct SolarDto {
17 pub day: i32,
18 pub month: i32,
19 pub year: i32,
20 pub day_of_week: usize,
21 pub day_of_week_name: String,
22 pub date_string: String,
23}
24
25#[derive(Debug, Clone, Serialize, Deserialize)]
26pub struct LunarDto {
27 pub day: i32,
28 pub month: i32,
29 pub year: i32,
30 pub is_leap_month: bool,
31 pub date_string: String,
32}
33
34#[derive(Debug, Clone, Serialize, Deserialize)]
35pub struct NguHanhDto {
36 pub can: String,
37 pub chi: String,
38}
39
40#[derive(Debug, Clone, Serialize, Deserialize)]
41pub struct CanChiDto {
42 pub can_index: usize,
43 pub chi_index: usize,
44 pub can: String,
45 pub chi: String,
46 pub full: String,
47 pub con_giap: String,
48 pub ngu_hanh: NguHanhDto,
49}
50
51#[derive(Debug, Clone, Serialize, Deserialize)]
52pub struct CanChiInfoDto {
53 pub day: CanChiDto,
54 pub month: CanChiDto,
55 pub year: CanChiDto,
56 pub full: String,
57}
58
59#[derive(Debug, Clone, Serialize, Deserialize)]
60pub struct TietKhiDto {
61 pub index: usize,
62 pub name: String,
63 pub description: String,
64 pub longitude: i32,
65 pub current_longitude: f64,
66 pub season: String,
67}
68
69#[derive(Debug, Clone, Serialize, Deserialize)]
70pub struct HourInfoDto {
71 pub hour_index: usize,
72 pub hour_chi: String,
73 pub time_range: String,
74 pub star: String,
75 pub is_good: bool,
76}
77
78#[derive(Debug, Clone, Serialize, Deserialize)]
79pub struct GioHoangDaoDto {
80 pub day_chi: String,
81 pub good_hour_count: usize,
82 pub good_hours: Vec<HourInfoDto>,
83 pub all_hours: Vec<HourInfoDto>,
84 pub summary: String,
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize)]
88pub struct DayElementDto {
89 pub na_am: String,
90 pub element: String,
91 pub can_element: String,
92 pub chi_element: String,
93 pub evidence: Option<RuleEvidenceDto>,
94}
95
96#[derive(Debug, Clone, Serialize, Deserialize)]
97pub struct DayConflictDto {
98 pub opposing_chi: String,
99 pub opposing_con_giap: String,
100 pub tuoi_xung: Vec<String>,
101 pub sat_huong: String,
102 pub evidence: Option<RuleEvidenceDto>,
103}
104
105#[derive(Debug, Clone, Serialize, Deserialize)]
106pub struct TravelDirectionDto {
107 pub xuat_hanh_huong: String,
108 pub tai_than: String,
109 pub hy_than: String,
110 pub evidence: Option<RuleEvidenceDto>,
111}
112
113#[derive(Debug, Clone, Serialize, Deserialize)]
114pub struct RuleEvidenceDto {
115 pub source_id: String,
116 pub method: String,
117 pub profile: String,
118}
119
120#[derive(Debug, Clone, Serialize, Deserialize)]
121pub struct DayStarDto {
122 pub system: String,
123 pub index: usize,
124 pub name: String,
125 pub quality: String,
126 pub evidence: Option<RuleEvidenceDto>,
127}
128
129#[derive(Debug, Clone, Serialize, Deserialize)]
130pub struct StarRuleEvidenceDto {
131 pub name: String,
132 pub quality: String,
133 pub category: String,
134 pub source_id: String,
135 pub method: String,
136 pub profile: String,
137}
138
139#[derive(Debug, Clone, Serialize, Deserialize)]
140pub struct DayStarsDto {
141 pub cat_tinh: Vec<String>,
142 pub sat_tinh: Vec<String>,
143 pub day_star: Option<DayStarDto>,
144 pub star_system: Option<String>,
145 pub evidence: Option<RuleEvidenceDto>,
146 pub matched_rules: Vec<StarRuleEvidenceDto>,
147}
148
149#[derive(Debug, Clone, Serialize, Deserialize)]
150pub struct DayDeityDto {
151 pub name: String,
152 pub classification: String,
153 pub evidence: Option<RuleEvidenceDto>,
154}
155
156#[derive(Debug, Clone, Serialize, Deserialize)]
157pub struct XungHopDto {
158 pub luc_xung: String,
159 pub tam_hop: Vec<String>,
160 pub tu_hanh_xung: Vec<String>,
161 pub liu_he: Option<String>,
162 pub xiang_hai: Option<String>,
163 pub xiang_xing: Option<Vec<String>>,
164}
165
166#[derive(Debug, Clone, Serialize, Deserialize)]
167pub struct TangCanDto {
168 pub main: String,
169 pub central: String,
170 pub residual: String,
171 pub strength: [u8; 3],
172}
173
174#[derive(Debug, Clone, Serialize, Deserialize)]
175pub struct TrucDto {
176 pub index: usize,
177 pub name: String,
178 pub quality: String,
179 pub evidence: Option<RuleEvidenceDto>,
180}
181
182#[derive(Debug, Clone, Serialize, Deserialize)]
183pub struct DayTenGodsDto {
184 pub to_year_stem: Option<ThapThanResultDto>,
186 pub to_self: Option<ThapThanResultDto>,
188}
189
190#[derive(Debug, Clone, Serialize, Deserialize)]
191pub struct ThapThanResultDto {
192 pub label: String,
193 pub relation: String,
194 pub same_polarity: bool,
195 pub evidence: RuleEvidenceDto,
196}
197
198#[derive(Debug, Clone, Serialize, Deserialize)]
199pub struct DayTabooDto {
200 pub rule_id: String,
201 pub name: String,
202 pub severity: String,
203 pub reason: String,
204 pub evidence: Option<RuleEvidenceDto>,
205}
206
207#[derive(Debug, Clone, Serialize, Deserialize)]
208pub struct DayFortuneDto {
209 pub ruleset_id: String,
210 pub ruleset_version: String,
211 pub profile: String,
212 pub day_element: DayElementDto,
213 pub conflict: DayConflictDto,
214 pub travel: TravelDirectionDto,
215 pub stars: DayStarsDto,
216 pub day_deity: Option<DayDeityDto>,
217 pub taboos: Vec<DayTabooDto>,
218 pub xung_hop: XungHopDto,
219 pub truc: TrucDto,
220 pub tang_can: Option<TangCanDto>,
221 pub ten_gods: Option<DayTenGodsDto>,
223 #[serde(skip_serializing_if = "Option::is_none")]
225 pub tu_menh: Option<KuaResultDto>,
226}
227
228#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
229#[serde(rename_all = "snake_case")]
230pub enum RecommendationScopeDto {
231 GeneralDay,
232}
233
234#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
235#[serde(rename_all = "snake_case")]
236pub enum RecommendationBucketDto {
237 Nen,
238 CoThe,
239 Tranh,
240 KyManh,
241}
242
243#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
244#[serde(rename_all = "snake_case")]
245pub enum RecommendationSeverityDto {
246 Primary,
247 Supporting,
248 Override,
249}
250
251#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
252#[serde(rename_all = "snake_case")]
253pub enum RecommendationEvidenceSourceDto {
254 DayGuidance,
255 Truc,
256 Stars,
257 DayDeity,
258 Taboo,
259 XungHop,
260 TietKhi,
261 GioHoangDao,
262 Travel,
263 ProductRule,
264}
265
266#[derive(Debug, Clone, Serialize, Deserialize)]
267pub struct ActivityLabelDto {
268 pub vi: String,
269 pub en: String,
270}
271
272#[derive(Debug, Clone, Serialize, Deserialize)]
273pub struct RecommendationEvidenceDto {
274 pub source: RecommendationEvidenceSourceDto,
275 pub code: String,
276 pub note: String,
277}
278
279#[derive(Debug, Clone, Serialize, Deserialize)]
280pub struct RecommendationReasonDto {
281 pub rule_id: String,
282 pub severity: RecommendationSeverityDto,
283 pub summary_vi: String,
284 pub summary_en: String,
285 pub evidence: RecommendationEvidenceDto,
286}
287
288#[derive(Debug, Clone, Serialize, Deserialize)]
289pub struct SynthesizedRecommendationDto {
290 pub activity_id: String,
291 pub label: ActivityLabelDto,
292 pub bucket: RecommendationBucketDto,
293 #[serde(default)]
294 pub reasons: Vec<RecommendationReasonDto>,
295}
296
297#[derive(Debug, Clone, Serialize, Deserialize)]
298pub struct DailyRecommendationsDto {
299 pub ruleset_id: String,
300 pub ruleset_version: String,
301 pub profile: String,
302 pub scope: RecommendationScopeDto,
303 pub version: String,
304 pub summary_vi: String,
305 pub summary_en: String,
306 #[serde(default)]
307 pub active_packs: Vec<ActiveRecommendationPackDto>,
308 #[serde(default)]
309 pub activities: Vec<SynthesizedRecommendationDto>,
310}
311
312#[derive(Debug, Clone, Serialize, Deserialize)]
313pub struct ActiveRecommendationPackDto {
314 pub pack_id: String,
315 pub version: String,
316 pub source_family: String,
317 pub mode: String,
318}
319
320#[derive(Debug, Clone, Serialize, Deserialize)]
321pub struct RulesetDefaultsDto {
322 pub tz_offset: f64,
323 #[serde(default, skip_serializing_if = "Option::is_none")]
324 pub meridian: Option<String>,
325}
326
327#[derive(Debug, Clone, Serialize, Deserialize)]
328pub struct RulesetSourceNoteDto {
329 pub family: String,
330 pub source_id: String,
331 pub note: String,
332}
333
334#[derive(Debug, Clone, Serialize, Deserialize)]
335pub struct RulesetCatalogEntryDto {
336 pub id: String,
337 pub canonical_id: String,
338 pub version: String,
339 pub region: String,
340 pub profile: String,
341 pub schema_version: String,
342 pub is_default: bool,
343 #[serde(default)]
344 pub aliases: Vec<String>,
345 pub defaults: RulesetDefaultsDto,
346 #[serde(default)]
347 pub source_notes: Vec<RulesetSourceNoteDto>,
348}
349
350#[derive(Debug, Clone, Serialize, Deserialize)]
351pub struct RecommendationPackCatalogEntryDto {
352 pub pack_id: String,
353 pub request_field: String,
354 pub version: String,
355 pub source_family: String,
356 pub mode: String,
357}
358
359#[derive(Debug, Clone, Serialize, Deserialize)]
360pub struct KuaResultDto {
361 pub kua: u8,
362 pub group: String,
363 pub favorable_directions: Vec<String>,
364 pub unfavorable_directions: Vec<String>,
365 pub convention: ConventionMetadataDto,
366}
367
368#[derive(Debug, Clone, Serialize, Deserialize)]
369pub struct ConventionMetadataDto {
370 pub year_basis: String,
371 pub kua_five_resolution: String,
372 pub gender_encoding: String,
373}
374
375#[derive(Debug, Clone, Serialize, Deserialize)]
376pub struct DayInfoDto {
377 pub ruleset_id: String,
378 pub ruleset_version: String,
379 pub profile: String,
380 pub solar: SolarDto,
381 pub lunar: LunarDto,
382 pub jd: i32,
383 pub canchi: CanChiInfoDto,
384 pub tiet_khi: TietKhiDto,
385 pub gio_hoang_dao: GioHoangDaoDto,
386 pub day_fortune: Option<DayFortuneDto>,
387 pub daily_recommendations: DailyRecommendationsDto,
388 #[serde(skip_serializing_if = "Option::is_none")]
389 pub contextual_recommendations: Option<DailyRecommendationsDto>,
390}
391
392#[derive(Debug, Clone, Serialize, Deserialize)]
393pub struct HolidayDto {
394 pub name: String,
395 pub description: String,
396 pub solar_day: i32,
397 pub solar_month: i32,
398 pub solar_year: i32,
399 pub lunar_day: Option<i32>,
400 pub lunar_month: Option<i32>,
401 pub lunar_year: Option<i32>,
402 pub is_solar: bool,
403 pub category: String,
404 pub is_major: bool,
405}
406
407#[derive(Debug, Clone, Serialize, Deserialize)]
408pub struct LocalizedTextDto {
409 pub vi: String,
410 pub en: String,
411}
412
413#[derive(Debug, Clone, Serialize, Deserialize)]
414pub struct LocalizedListDto {
415 pub vi: Vec<String>,
416 pub en: Vec<String>,
417}
418
419#[derive(Debug, Clone, Serialize, Deserialize)]
420pub struct FoodInsightDto {
421 pub name: LocalizedTextDto,
422 pub description: LocalizedTextDto,
423}
424
425#[derive(Debug, Clone, Serialize, Deserialize)]
426pub struct TabooInsightDto {
427 pub action: LocalizedTextDto,
428 pub reason: LocalizedTextDto,
429}
430
431#[derive(Debug, Clone, Serialize, Deserialize)]
432pub struct ProverbInsightDto {
433 pub text: String,
434 pub meaning: LocalizedTextDto,
435}
436
437#[derive(Debug, Clone, Serialize, Deserialize)]
438pub struct RegionsInsightDto {
439 pub north: LocalizedTextDto,
440 pub central: LocalizedTextDto,
441 pub south: LocalizedTextDto,
442}
443
444#[derive(Debug, Clone, Serialize, Deserialize)]
445pub struct FestivalInsightDto {
446 pub names: LocalizedListDto,
447 pub origin: Option<LocalizedTextDto>,
448 pub activities: Option<LocalizedListDto>,
449 pub food: Vec<FoodInsightDto>,
450 pub taboos: Vec<TabooInsightDto>,
451 pub proverbs: Vec<ProverbInsightDto>,
452 pub regions: Option<RegionsInsightDto>,
453 pub category: String,
454 pub is_major: bool,
455}
456
457#[derive(Debug, Clone, Serialize, Deserialize)]
458pub struct HolidayInsightDto {
459 pub names: LocalizedListDto,
460 pub origin: Option<LocalizedTextDto>,
461 pub significance: Option<LocalizedTextDto>,
462 pub activities: Option<LocalizedListDto>,
463 pub traditions: Option<LocalizedListDto>,
464 pub food: Vec<FoodInsightDto>,
465 pub taboos: Vec<TabooInsightDto>,
466 pub proverbs: Vec<ProverbInsightDto>,
467 pub regions: Option<RegionsInsightDto>,
468 pub category: String,
469 pub is_major: bool,
470}
471
472#[derive(Debug, Clone, Serialize, Deserialize)]
473pub struct UpcomingEventDto {
474 pub name: String,
475 pub days_left: i32,
476 pub is_lunar: bool,
477}
478
479#[derive(Debug, Clone, Serialize, Deserialize)]
480pub struct ElementInsightDto {
481 pub key: String,
482 pub name: LocalizedTextDto,
483 pub nature: LocalizedTextDto,
484}
485
486#[derive(Debug, Clone, Serialize, Deserialize)]
487pub struct CanInsightDto {
488 pub name: String,
489 pub element: String,
490 pub meaning: LocalizedTextDto,
491 pub nature: LocalizedTextDto,
492}
493
494#[derive(Debug, Clone, Serialize, Deserialize)]
495pub struct ChiInsightDto {
496 pub name: String,
497 pub animal: LocalizedTextDto,
498 pub element: String,
499 pub meaning: LocalizedTextDto,
500 pub hours: String,
501}
502
503#[derive(Debug, Clone, Serialize, Deserialize)]
504pub struct CanChiInsightDto {
505 pub can: CanInsightDto,
506 pub chi: ChiInsightDto,
507 pub element: Option<ElementInsightDto>,
508}
509
510#[derive(Debug, Clone, Serialize, Deserialize)]
511pub struct DayGuidanceDto {
512 pub good_for: LocalizedListDto,
513 pub avoid_for: LocalizedListDto,
514}
515
516#[derive(Debug, Clone, Serialize, Deserialize)]
517pub struct TietKhiInsightDto {
518 pub id: String,
519 pub name: LocalizedTextDto,
520 pub longitude: i32,
521 pub meaning: LocalizedTextDto,
522 pub astronomy: LocalizedTextDto,
523 pub agriculture: LocalizedListDto,
524 pub health: LocalizedListDto,
525 pub weather: LocalizedTextDto,
526}
527
528#[derive(Debug, Clone, Serialize, Deserialize)]
529pub struct NaAmInsightDto {
530 pub na_am: String,
531 pub element: String,
532 pub meaning: LocalizedTextDto,
533}
534
535#[derive(Debug, Clone, Serialize, Deserialize)]
536pub struct TrucInsightDto {
537 pub name: String,
538 pub quality: String,
539 pub meaning: LocalizedTextDto,
540 pub good_for: LocalizedListDto,
541 pub avoid_for: LocalizedListDto,
542}
543
544#[derive(Debug, Clone, Serialize, Deserialize)]
545pub struct DayDeityInsightDto {
546 pub name: String,
547 pub classification: String,
548 pub classification_meaning: LocalizedTextDto,
549 pub deity_meaning: Option<LocalizedTextDto>,
550}
551
552#[derive(Debug, Clone, Serialize, Deserialize)]
553pub struct StarsInsightDto {
554 pub cat_tinh: Vec<String>,
555 pub sat_tinh: Vec<String>,
556 pub day_star: Option<String>,
557 pub day_star_quality: Option<String>,
558}
559
560#[derive(Debug, Clone, Serialize, Deserialize)]
561pub struct TabooInsightItemDto {
562 pub name: String,
563 pub severity: String,
564 pub reason: String,
565}
566
567#[derive(Debug, Clone, Serialize, Deserialize)]
568pub struct TravelInsightDto {
569 pub xuat_hanh_huong: String,
570 pub tai_than: String,
571 pub hy_than: String,
572}
573
574#[derive(Debug, Clone, Serialize, Deserialize)]
575pub struct XungHopInsightDto {
576 pub luc_xung: String,
577 pub tam_hop: Vec<String>,
578 pub liu_he: Option<String>,
579 pub xiang_hai: Option<String>,
580}
581
582#[derive(Debug, Clone, Serialize, Deserialize)]
583pub struct TangCanInsightDto {
584 pub main: String,
585 pub central: String,
586 pub residual: String,
587 pub strength: [u8; 3],
588}
589
590#[derive(Debug, Clone, Serialize, Deserialize)]
591pub struct TenGodsEntryInsightDto {
592 pub label: String,
593 pub name: LocalizedTextDto,
594 pub meaning: LocalizedTextDto,
595 pub relation: String,
596 pub same_polarity: bool,
597}
598
599#[derive(Debug, Clone, Serialize, Deserialize)]
600pub struct TenGodsInsightDto {
601 pub to_year_stem: Option<TenGodsEntryInsightDto>,
602 pub to_self: Option<TenGodsEntryInsightDto>,
603}
604
605#[derive(Debug, Clone, Serialize, Deserialize)]
606pub struct HourInsightEntryDto {
607 pub chi: String,
608 pub time_range: String,
609 pub star: String,
610}
611
612#[derive(Debug, Clone, Serialize, Deserialize)]
613pub struct HoursInsightDto {
614 pub good_hour_count: usize,
615 pub good_hours: Vec<HourInsightEntryDto>,
616}
617
618#[derive(Debug, Clone, Serialize, Deserialize)]
619pub struct TuMenhInsightDto {
620 pub kua: u8,
621 pub group: String,
622 pub trigram: LocalizedTextDto,
623 pub direction: LocalizedTextDto,
624 pub meaning: LocalizedTextDto,
625 pub group_meaning: LocalizedTextDto,
626 pub favorable_directions: Vec<String>,
627 pub unfavorable_directions: Vec<String>,
628}
629
630#[derive(Debug, Clone, Serialize, Deserialize)]
631pub struct DaiVanPillarInsightDto {
632 pub index: usize,
633 pub can_chi: String,
634 pub start_age: f64,
635 pub end_age: f64,
636 pub element: String,
637 pub element_meaning: LocalizedTextDto,
638}
639
640#[derive(Debug, Clone, Serialize, Deserialize)]
641pub struct DaiVanInsightDto {
642 pub direction: String,
643 pub direction_meaning: LocalizedTextDto,
644 pub start_age: String,
645 pub current_pillar: Option<DaiVanPillarInsightDto>,
646 pub all_pillars: Vec<DaiVanPillarInsightDto>,
647 pub phases_meaning: LocalizedTextDto,
648}
649
650#[derive(Debug, Clone, Serialize, Deserialize)]
651pub struct DayInsightDto {
652 pub solar: SolarDto,
653 pub lunar: LunarDto,
654 #[serde(skip_serializing_if = "Option::is_none")]
655 pub festival: Option<FestivalInsightDto>,
656 #[serde(skip_serializing_if = "Option::is_none")]
657 pub holiday: Option<HolidayInsightDto>,
658 #[serde(skip_serializing_if = "Option::is_none")]
659 pub canchi: Option<CanChiInsightDto>,
660 #[serde(skip_serializing_if = "Option::is_none")]
661 pub day_guidance: Option<DayGuidanceDto>,
662 #[serde(skip_serializing_if = "Option::is_none")]
663 pub tiet_khi: Option<TietKhiInsightDto>,
664 #[serde(skip_serializing_if = "Option::is_none")]
665 pub na_am: Option<NaAmInsightDto>,
666 #[serde(skip_serializing_if = "Option::is_none")]
667 pub truc: Option<TrucInsightDto>,
668 #[serde(skip_serializing_if = "Option::is_none")]
669 pub day_deity: Option<DayDeityInsightDto>,
670 #[serde(skip_serializing_if = "Option::is_none")]
671 pub stars: Option<StarsInsightDto>,
672 #[serde(skip_serializing_if = "Option::is_none")]
673 pub taboos: Option<Vec<TabooInsightItemDto>>,
674 #[serde(skip_serializing_if = "Option::is_none")]
675 pub travel: Option<TravelInsightDto>,
676 #[serde(skip_serializing_if = "Option::is_none")]
677 pub xung_hop: Option<XungHopInsightDto>,
678 #[serde(skip_serializing_if = "Option::is_none")]
679 pub tang_can: Option<TangCanInsightDto>,
680 #[serde(skip_serializing_if = "Option::is_none")]
681 pub ten_gods: Option<TenGodsInsightDto>,
682 #[serde(skip_serializing_if = "Option::is_none")]
683 pub hours: Option<HoursInsightDto>,
684 #[serde(skip_serializing_if = "Option::is_none")]
685 pub tu_menh: Option<TuMenhInsightDto>,
686 #[serde(skip_serializing_if = "Option::is_none")]
687 pub dai_van: Option<DaiVanInsightDto>,
688}
689
690#[derive(Debug, Clone, Serialize, Deserialize)]
692pub struct NaAmLookupResultDto {
693 pub cycle_index: u8,
695 pub can: String,
697 pub chi: String,
699 pub na_am: String,
701 pub element: String,
703 pub source_id: String,
705 pub method: String,
707 pub profile: String,
709}
710
711#[derive(Debug, Clone, Serialize, Deserialize)]
713pub struct NaAmErrorDto {
714 pub error: String,
716 pub message: String,
718}
719
720#[derive(Debug, Clone, Serialize, Deserialize)]
722pub enum NaAmResponseDto {
723 Success(NaAmLookupResultDto),
724 Error(NaAmErrorDto),
725}
726
727#[cfg(test)]
728mod tests {
729 use super::*;
730
731 #[test]
732 fn day_fortune_dto_has_optional_ten_gods_and_tu_menh_fields() {
733 let dto = DayFortuneDto {
735 ruleset_id: "test".to_string(),
736 ruleset_version: "v1".to_string(),
737 profile: "baseline".to_string(),
738 day_element: DayElementDto {
739 na_am: "test".to_string(),
740 element: "Kim".to_string(),
741 can_element: "Mộc".to_string(),
742 chi_element: "Thổ".to_string(),
743 evidence: None,
744 },
745 conflict: DayConflictDto {
746 opposing_chi: "Tuất".to_string(),
747 opposing_con_giap: "Tuất (Chó)".to_string(),
748 tuoi_xung: vec![],
749 sat_huong: "Nam".to_string(),
750 evidence: None,
751 },
752 travel: TravelDirectionDto {
753 xuat_hanh_huong: "Đông Nam".to_string(),
754 tai_than: "Tây Nam".to_string(),
755 hy_than: "Đông Bắc".to_string(),
756 evidence: None,
757 },
758 stars: DayStarsDto {
759 cat_tinh: vec![],
760 sat_tinh: vec![],
761 day_star: None,
762 star_system: None,
763 evidence: None,
764 matched_rules: vec![],
765 },
766 day_deity: None,
767 taboos: vec![],
768 xung_hop: XungHopDto {
769 luc_xung: "Tuất".to_string(),
770 tam_hop: vec![],
771 tu_hanh_xung: vec![],
772 liu_he: None,
773 xiang_hai: None,
774 xiang_xing: None,
775 },
776 truc: TrucDto {
777 index: 0,
778 name: "Kiến".to_string(),
779 quality: "cat".to_string(),
780 evidence: None,
781 },
782 tang_can: None,
783 ten_gods: None,
784 tu_menh: None,
785 };
786
787 let _ = dto.ten_gods;
789 let _ = dto.tu_menh;
790 }
791
792 #[test]
793 fn day_ten_gods_dto_serializes_with_snake_case() {
794 let ten_gods = DayTenGodsDto {
796 to_year_stem: None,
797 to_self: None,
798 };
799
800 let json = serde_json::to_string(&ten_gods).expect("serialize");
801 assert!(json.contains("\"to_year_stem\""));
803 assert!(json.contains("\"to_self\""));
804 }
805}