fastn_resolved/
kind.rs

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    }, // the full name of the record (full document name.record name)
11    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}