1#[derive(Debug, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
2pub enum Kind {
3 String,
4 Object,
5 Integer,
6 Decimal,
7 Boolean,
8 Record {
9 name: String,
10 }, OrType {
12 name: String,
13 variant: Option<String>,
14 full_variant: Option<String>,
15 },
16 List {
17 kind: Box<Kind>,
18 },
19 Optional {
20 kind: Box<Kind>,
21 },
22 UI {
23 name: Option<String>,
24 subsection_source: bool,
25 is_web_component: bool,
26 },
27 Constant {
28 kind: Box<Kind>,
29 },
30 Void,
31 Module,
32 KwArgs,
33}
34
35impl Kind {
36 pub fn get_name(&self) -> String {
37 match self {
38 Kind::String { .. } => "string".to_string(),
39 Kind::Integer { .. } => "integer".to_string(),
40 Kind::Boolean { .. } => "boolean".to_string(),
41 Kind::Decimal { .. } => "decimal".to_string(),
42 Kind::Constant { .. } => "constant".to_string(),
43 Kind::List { .. } => "list".to_string(),
44 Kind::Object { .. } => "object".to_string(),
45 Kind::OrType { name, .. } => name.clone(),
46 Kind::Optional { .. } => "optional".to_string(),
47 Kind::Void { .. } => "void".to_string(),
48 Kind::Module => "module".to_string(),
49 Kind::KwArgs => "kw-args".to_string(),
50 Kind::UI { name, .. } => name.clone().unwrap_or("record".to_string()),
51 Kind::Record { name } => name.clone(),
52 }
53 }
54
55 pub fn is_same_as(&self, other: &Self) -> bool {
56 match (self, other) {
57 (Self::UI { .. }, Self::UI { .. }) => true,
58 (Self::OrType { name: n1, .. }, Self::OrType { name: n2, .. }) => n1.eq(n2),
59 (Self::Optional { kind, .. }, _) => kind.is_same_as(other),
60 (_, Self::Optional { kind: other, .. }) => self.is_same_as(other),
61 (Self::List { kind: k1 }, Self::List { kind: k2 }) => k1.is_same_as(k2),
62 _ => self.eq(other),
63 }
64 }
65
66 pub fn into_kind_data(self) -> KindData {
67 KindData::new(self)
68 }
69
70 pub fn string() -> Kind {
71 Kind::String
72 }
73
74 pub fn integer() -> Kind {
75 Kind::Integer
76 }
77
78 pub fn decimal() -> Kind {
79 Kind::Decimal
80 }
81
82 pub fn boolean() -> Kind {
83 Kind::Boolean
84 }
85
86 pub fn module() -> Kind {
87 Kind::Module
88 }
89
90 pub fn kwargs() -> Kind {
91 Kind::KwArgs
92 }
93
94 pub fn ui() -> Kind {
95 Kind::UI {
96 name: None,
97 subsection_source: false,
98 is_web_component: false,
99 }
100 }
101
102 pub fn ui_with_name(name: &str) -> Kind {
103 Kind::UI {
104 name: Some(name.to_string()),
105 subsection_source: false,
106 is_web_component: false,
107 }
108 }
109
110 pub fn web_ui_with_name(name: &str) -> Kind {
111 Kind::UI {
112 name: Some(name.to_string()),
113 subsection_source: false,
114 is_web_component: true,
115 }
116 }
117
118 pub fn subsection_ui() -> Kind {
119 Kind::UI {
120 name: None,
121 subsection_source: true,
122 is_web_component: false,
123 }
124 }
125
126 pub fn object() -> Kind {
127 Kind::Object
128 }
129
130 pub fn void() -> Kind {
131 Kind::Void
132 }
133
134 pub fn record(name: &str) -> Kind {
135 Kind::Record {
136 name: name.to_string(),
137 }
138 }
139
140 pub fn or_type(name: &str) -> Kind {
141 Kind::OrType {
142 name: name.to_string(),
143 variant: None,
144 full_variant: None,
145 }
146 }
147
148 pub fn or_type_with_variant(name: &str, variant: &str, full_variant: &str) -> Kind {
149 Kind::OrType {
150 name: name.to_string(),
151 variant: Some(variant.to_string()),
152 full_variant: Some(full_variant.to_string()),
153 }
154 }
155
156 pub fn into_list(self) -> Kind {
157 Kind::List {
158 kind: Box::new(self),
159 }
160 }
161
162 pub fn into_optional(self) -> Kind {
163 Kind::Optional {
164 kind: Box::new(self),
165 }
166 }
167
168 pub fn inner(self) -> Kind {
169 match self {
170 Kind::Optional { kind } => kind.as_ref().to_owned(),
171 t => t,
172 }
173 }
174
175 pub fn mut_inner(&mut self) -> &mut Kind {
176 match self {
177 Kind::Optional { kind } => kind,
178 t => t,
179 }
180 }
181
182 pub fn ref_inner(&self) -> &Kind {
183 match self {
184 Kind::Optional { kind } => kind,
185 t => t,
186 }
187 }
188
189 pub fn inner_list(self) -> Kind {
190 match self {
191 Kind::List { kind } => kind.as_ref().to_owned(),
192 t => t,
193 }
194 }
195
196 pub fn ref_inner_list(&self) -> &Kind {
197 match self {
198 Kind::List { kind } => kind,
199 t => t,
200 }
201 }
202
203 pub fn is_list(&self) -> bool {
204 matches!(self, Kind::List { .. })
205 }
206
207 pub fn is_subsection_ui(&self) -> bool {
208 matches!(
209 self,
210 Kind::UI {
211 subsection_source: true,
212 ..
213 }
214 )
215 }
216
217 pub fn is_ui(&self) -> bool {
218 matches!(self, Kind::UI { .. })
219 }
220
221 pub fn is_optional(&self) -> bool {
222 matches!(self, Kind::Optional { .. })
223 }
224
225 pub fn is_record(&self) -> bool {
226 matches!(self, Kind::Record { .. })
227 }
228
229 pub fn is_or_type(&self) -> bool {
230 matches!(self, Kind::OrType { .. })
231 }
232
233 pub fn is_string(&self) -> bool {
234 matches!(self, Kind::String { .. })
235 }
236
237 pub fn is_module(&self) -> bool {
238 matches!(self, Kind::Module)
239 }
240
241 pub fn is_kwargs(&self) -> bool {
242 matches!(self, Kind::KwArgs)
243 }
244
245 pub fn is_integer(&self) -> bool {
246 matches!(self, Kind::Integer { .. })
247 }
248
249 pub fn is_boolean(&self) -> bool {
250 matches!(self, Kind::Boolean { .. })
251 }
252
253 pub fn is_decimal(&self) -> bool {
254 matches!(self, Kind::Decimal { .. })
255 }
256
257 pub fn is_void(&self) -> bool {
258 matches!(self, Kind::Void { .. })
259 }
260
261 pub fn get_or_type(&self) -> Option<(String, Option<String>, Option<String>)> {
262 match self {
263 Kind::OrType {
264 name,
265 variant,
266 full_variant,
267 } => Some((name.to_owned(), variant.to_owned(), full_variant.to_owned())),
268 _ => None,
269 }
270 }
271
272 pub fn get_record_name(&self) -> Option<&str> {
273 match self {
274 fastn_resolved::Kind::Record { ref name, .. } => Some(name),
275 _ => None,
276 }
277 }
278
279 pub fn get_or_type_name(&self) -> Option<&str> {
280 match self {
281 fastn_resolved::Kind::OrType { ref name, .. } => Some(name),
282 _ => None,
283 }
284 }
285
286 pub fn is_or_type_with_variant(&self, or_type_name: &str, variant_name: &str) -> bool {
287 matches!(self, Kind::OrType { name, variant, .. } if name.eq(or_type_name) && variant.is_some() && variant.as_ref().unwrap().eq(variant_name))
288 }
289}
290
291#[derive(Debug, Clone, PartialEq, serde::Deserialize, serde::Serialize)]
292pub struct KindData {
293 pub kind: Kind,
294 pub caption: bool,
295 pub body: bool,
296}
297
298impl KindData {
299 pub fn new(kind: Kind) -> KindData {
300 KindData {
301 kind,
302 caption: false,
303 body: false,
304 }
305 }
306
307 pub fn caption(self) -> KindData {
308 let mut kind = self;
309 kind.caption = true;
310 kind
311 }
312
313 pub fn body(self) -> KindData {
314 let mut kind = self;
315 kind.body = true;
316 kind
317 }
318
319 pub fn caption_or_body(self) -> KindData {
320 let mut kind = self;
321 kind.caption = true;
322 kind.body = true;
323 kind
324 }
325
326 pub fn is_list(&self) -> bool {
327 self.kind.is_list()
328 }
329
330 pub fn is_or_type(&self) -> bool {
331 self.kind.is_or_type()
332 }
333
334 pub fn is_optional(&self) -> bool {
335 self.kind.is_optional()
336 }
337
338 pub fn into_optional(self) -> Self {
339 KindData {
340 caption: self.caption,
341 body: self.body,
342 kind: self.kind.into_optional(),
343 }
344 }
345
346 pub fn is_string(&self) -> bool {
347 self.kind.is_string()
348 }
349
350 pub fn is_module(&self) -> bool {
351 self.kind.is_module()
352 }
353
354 pub fn is_integer(&self) -> bool {
355 self.kind.is_integer()
356 }
357
358 pub fn is_record(&self) -> bool {
359 self.kind.is_record()
360 }
361
362 pub fn is_boolean(&self) -> bool {
363 self.kind.is_boolean()
364 }
365
366 pub fn is_subsection_ui(&self) -> bool {
367 self.kind.is_subsection_ui()
368 }
369
370 pub fn is_ui(&self) -> bool {
371 self.kind.is_ui()
372 }
373
374 pub fn is_decimal(&self) -> bool {
375 self.kind.is_decimal()
376 }
377
378 pub fn is_void(&self) -> bool {
379 self.kind.is_void()
380 }
381
382 pub fn is_kwargs(&self) -> bool {
383 self.kind.is_kwargs()
384 }
385
386 pub fn optional(self) -> KindData {
387 KindData {
388 kind: Kind::Optional {
389 kind: Box::new(self.kind),
390 },
391 caption: self.caption,
392 body: self.body,
393 }
394 }
395
396 pub fn list(self) -> KindData {
397 KindData {
398 kind: Kind::List {
399 kind: Box::new(self.kind),
400 },
401 caption: self.caption,
402 body: self.body,
403 }
404 }
405
406 pub fn constant(self) -> KindData {
407 KindData {
408 kind: Kind::Constant {
409 kind: Box::new(self.kind),
410 },
411 caption: self.caption,
412 body: self.body,
413 }
414 }
415
416 pub fn inner_list(self) -> KindData {
417 let kind = match self.kind {
418 Kind::List { kind } => kind.as_ref().to_owned(),
419 t => t,
420 };
421 KindData {
422 kind,
423 caption: self.caption,
424 body: self.body,
425 }
426 }
427
428 pub fn inner(self) -> KindData {
429 let kind = match self.kind {
430 Kind::Optional { kind } => kind.as_ref().to_owned(),
431 t => t,
432 };
433 KindData {
434 kind,
435 caption: self.caption,
436 body: self.body,
437 }
438 }
439}