1use crate::prelude::*;
2
3#[derive(Clone, Debug, Serialize)]
8pub struct Enum {
9 def: Def,
10 source_key: &'static str,
11 variants: &'static [EnumVariant],
12 ty: Type,
13}
14
15impl Enum {
16 #[must_use]
17 pub const fn new(
18 def: Def,
19 source_key: &'static str,
20 variants: &'static [EnumVariant],
21 ty: Type,
22 ) -> Self {
23 Self {
24 def,
25 source_key,
26 variants,
27 ty,
28 }
29 }
30
31 #[must_use]
32 pub const fn def(&self) -> &Def {
33 &self.def
34 }
35
36 #[must_use]
38 pub const fn source_key(&self) -> &'static str {
39 self.source_key
40 }
41
42 #[must_use]
43 pub const fn variants(&self) -> &'static [EnumVariant] {
44 self.variants
45 }
46
47 #[must_use]
48 pub const fn ty(&self) -> &Type {
49 &self.ty
50 }
51}
52
53impl MacroNode for Enum {
54 fn as_any(&self) -> &dyn std::any::Any {
55 self
56 }
57}
58
59impl ValidateNode for Enum {
60 fn validate(&self) -> Result<(), ErrorTree> {
61 let mut errs = ErrorTree::new();
62 validate_source_key(
63 &mut errs,
64 "enum type",
65 self.source_key(),
66 icydb_schema::TypeSourceKey::try_new,
67 );
68 let mut seen = std::collections::BTreeSet::new();
69 for variant in self.variants() {
70 if !seen.insert(variant.source_key()) {
71 err!(
72 errs,
73 "duplicate enum variant source key '{}'",
74 variant.source_key(),
75 );
76 }
77 }
78 errs.result()
79 }
80}
81
82impl VisitableNode for Enum {
83 fn route_key(&self) -> String {
84 self.def().path()
85 }
86
87 fn drive<V: Visitor>(&self, v: &mut V) {
88 self.def().accept(v);
89 for node in self.variants() {
90 node.accept(v);
91 }
92 self.ty().accept(v);
93 }
94}
95
96#[derive(Clone, Debug, Serialize)]
101pub struct EnumVariant {
102 source_key: &'static str,
103 ident: &'static str,
104
105 #[serde(skip_serializing_if = "Option::is_none")]
106 value: Option<Value>,
107}
108
109impl EnumVariant {
110 #[must_use]
111 pub const fn new(source_key: &'static str, ident: &'static str, value: Option<Value>) -> Self {
112 Self {
113 source_key,
114 ident,
115 value,
116 }
117 }
118
119 #[must_use]
121 pub const fn source_key(&self) -> &'static str {
122 self.source_key
123 }
124
125 #[must_use]
126 pub const fn ident(&self) -> &'static str {
127 self.ident
128 }
129
130 #[must_use]
131 pub const fn value(&self) -> Option<&Value> {
132 self.value.as_ref()
133 }
134}
135
136impl ValidateNode for EnumVariant {
137 fn validate(&self) -> Result<(), ErrorTree> {
138 let mut errs = ErrorTree::new();
139 validate_source_key(
140 &mut errs,
141 "enum variant",
142 self.source_key(),
143 icydb_schema::TypeSourceKey::try_new,
144 );
145 errs.result()
146 }
147}
148
149impl VisitableNode for EnumVariant {
150 fn drive<V: Visitor>(&self, v: &mut V) {
151 if let Some(node) = self.value() {
152 node.accept(v);
153 }
154 }
155}