1mod codegen;
2mod ids;
3mod internal;
4mod normalize;
5mod rename;
6mod semantic;
7mod subst;
8mod symbol;
9mod visit;
10
11pub use self::codegen::*;
12pub use self::ids::ensure_symbol_ids;
13pub use self::normalize::{
14 CircularDependencyResolutionStage, Consolidation, Naming, NamingResolutionStage,
15 NormalizationError, NormalizationPipeline, NormalizationStage, Normalizer, PipelineBuilder,
16 ResolutionStrategy, TypeConsolidationStage,
17};
18pub use self::semantic::*;
19pub use self::subst::{mk_subst, Instantiate, Substitute};
20pub use self::symbol::{SymbolId, SymbolKind, STDLIB_TYPES, STDLIB_TYPE_PREFIXES};
21pub use self::visit::{VisitMut, Visitor};
22
23#[cfg(feature = "glob")]
24pub use self::rename::Glob;
25
26#[cfg(feature = "glob")]
27pub use glob::PatternError;
28
29pub use self::rename::*;
30use core::fmt;
31use std::collections::BTreeSet;
32use std::{
33 collections::HashMap,
34 ops::{ControlFlow, Index},
35};
36
37#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
38pub struct Schema {
39 #[serde(skip_serializing, default)]
40 pub id: SymbolId,
41
42 pub name: String,
43
44 #[serde(skip_serializing_if = "String::is_empty", default)]
45 pub description: String,
46
47 #[serde(skip_serializing_if = "Vec::is_empty", default)]
48 pub functions: Vec<Function>,
49
50 #[serde(skip_serializing_if = "Typespace::is_empty", default)]
51 pub input_types: Typespace,
52
53 #[serde(skip_serializing_if = "Typespace::is_empty", default)]
54 pub output_types: Typespace,
55}
56
57impl Default for Schema {
58 fn default() -> Self {
59 Self::new()
60 }
61}
62
63impl Schema {
64 pub fn new() -> Self {
65 Schema {
66 id: SymbolId::default(),
67 name: String::new(),
68 description: String::new(),
69 functions: Vec::new(),
70 input_types: Typespace::new(),
71 output_types: Typespace::new(),
72 }
73 }
74
75 pub fn name(&self) -> &str {
76 self.name.as_str()
77 }
78
79 pub fn description(&self) -> &str {
80 self.description.as_str()
81 }
82
83 pub fn functions(&self) -> std::slice::Iter<'_, Function> {
84 self.functions.iter()
85 }
86
87 pub fn input_types(&self) -> &Typespace {
88 &self.input_types
89 }
90
91 pub fn is_input_type(&self, name: &str) -> bool {
92 self.input_types.has_type(name)
93 }
94
95 pub fn output_types(&self) -> &Typespace {
96 &self.output_types
97 }
98
99 pub fn is_output_type(&self, name: &str) -> bool {
100 self.output_types.has_type(name)
101 }
102
103 pub fn extend(&mut self, other: Self) {
104 let Self {
105 id: _,
106 functions,
107 input_types,
108 output_types,
109 name: _,
110 description: _,
111 } = other;
112 self.functions.extend(functions);
113 self.input_types.extend(input_types);
114 self.output_types.extend(output_types);
115 }
116
117 pub fn prepend_path(&mut self, path: &str) {
118 if path.is_empty() {
119 return;
120 }
121 for function in self.functions.iter_mut() {
122 function.path = format!("{}{}", path, function.path);
123 }
124 }
125
126 pub fn consolidate_types(&mut self) -> Vec<String> {
127 loop {
130 let mut all_types = std::collections::HashSet::new();
131 let mut colliding_types = std::collections::HashSet::new();
132 let mut colliging_non_equal_types = std::collections::HashSet::new();
133
134 for input_type in self.input_types.types() {
135 all_types.insert(input_type.name().to_string());
136 if let Some(output_type) = self.output_types.get_type(input_type.name()) {
137 colliding_types.insert(input_type.name().to_string());
138 if input_type != output_type {
139 colliging_non_equal_types.insert(input_type.name().to_string());
140 }
141 }
142 }
143 for output_type in self.output_types.types() {
144 all_types.insert(output_type.name().to_string());
145 if let Some(input_type) = self.input_types.get_type(output_type.name()) {
146 colliding_types.insert(output_type.name().to_string());
147 if input_type != output_type {
148 colliging_non_equal_types.insert(output_type.name().to_string());
149 }
150 }
151 }
152
153 if colliging_non_equal_types.is_empty() {
154 let mut r: Vec<_> = all_types.into_iter().collect();
155 r.sort();
156 return r;
157 }
158
159 for type_name in colliging_non_equal_types.iter() {
160 let mut type_name_parts = type_name.split("::").collect::<Vec<_>>();
163 type_name_parts.insert(type_name_parts.len() - 1, "input");
164 self.rename_input_types(type_name.as_str(), &type_name_parts.join("::"));
165
166 let mut type_name_parts = type_name.split("::").collect::<Vec<_>>();
167 type_name_parts.insert(type_name_parts.len() - 1, "output");
168 self.rename_output_types(type_name.as_str(), &type_name_parts.join("::"));
169 }
170 }
171 }
172
173 pub fn get_type(&self, name: &str) -> Option<&Type> {
174 if let Some(t) = self.input_types.get_type(name) {
175 return Some(t);
176 }
177 if let Some(t) = self.output_types.get_type(name) {
178 return Some(t);
179 }
180 None
181 }
182
183 pub fn get_type_mut(&mut self, name: &str) -> Option<&mut Type> {
184 if let Some(t) = self.input_types.get_type_mut(name) {
185 return Some(t);
186 }
187 if let Some(t) = self.output_types.get_type_mut(name) {
188 return Some(t);
189 }
190 None
191 }
192
193 #[cfg(feature = "glob")]
194 pub fn glob_rename_types(
195 &mut self,
196 glob: &str,
197 replacer: &str,
198 ) -> Result<(), glob::PatternError> {
199 let pattern = glob.parse::<Glob>()?;
200 self.rename_types(&pattern, replacer);
201 Ok(())
202 }
203
204 pub fn rename_types(&mut self, pattern: impl Pattern, replacer: &str) -> usize {
205 self.rename_input_types(pattern, replacer) + self.rename_output_types(pattern, replacer)
206 }
207
208 fn rename_input_types(&mut self, pattern: impl Pattern, replacer: &str) -> usize {
209 match Renamer::new(pattern, replacer).visit_schema_inputs(self) {
210 ControlFlow::Continue(c) | ControlFlow::Break(c) => c,
211 }
212 }
213
214 fn rename_output_types(&mut self, pattern: impl Pattern, replacer: &str) -> usize {
215 match Renamer::new(pattern, replacer).visit_schema_outputs(self) {
216 ControlFlow::Continue(c) | ControlFlow::Break(c) => c,
217 }
218 }
219
220 pub fn fold_transparent_types(&mut self) {
221 #[derive(Debug)]
223 struct SubstVisitor {
224 strukt: Struct,
225 to: TypeReference,
226 }
227
228 impl SubstVisitor {
229 fn new(strukt: Struct) -> Self {
230 assert!(strukt.transparent && strukt.fields.len() == 1);
231 Self {
232 to: strukt.fields[0].type_ref.clone(),
233 strukt,
234 }
235 }
236 }
237
238 impl Visitor for SubstVisitor {
239 type Output = ();
240
241 fn visit_type_ref(
242 &mut self,
243 type_ref: &mut TypeReference,
244 ) -> ControlFlow<Self::Output, Self::Output> {
245 if type_ref.name == self.strukt.name {
246 let subst = subst::mk_subst(&self.strukt.parameters, &type_ref.arguments);
247 *type_ref = self.to.clone().subst(&subst);
248 }
249
250 type_ref.visit_mut(self)?;
251
252 ControlFlow::Continue(())
253 }
254 }
255
256 let transparent_types = self
257 .input_types()
258 .types()
259 .filter_map(|t| {
260 t.as_struct()
261 .filter(|i| i.transparent && i.fields.len() == 1)
262 .cloned()
263 })
264 .collect::<Vec<_>>();
265
266 for strukt in transparent_types {
267 self.input_types.remove_type(strukt.name());
268 let _ = SubstVisitor::new(strukt).visit_schema_inputs(self);
269 }
270
271 let transparent_types = self
272 .output_types()
273 .types()
274 .filter_map(|t| {
275 t.as_struct()
276 .filter(|i| i.transparent && i.fields.len() == 1)
277 .cloned()
278 })
279 .collect::<Vec<_>>();
280
281 for strukt in transparent_types {
282 self.output_types.remove_type(strukt.name());
283 let _ = SubstVisitor::new(strukt).visit_schema_outputs(self);
284 }
285 }
286}
287
288#[derive(Clone, serde::Serialize, serde::Deserialize, Default)]
289pub struct Typespace {
290 #[serde(skip_serializing_if = "Vec::is_empty", default)]
291 types: Vec<Type>,
292
293 #[serde(skip_serializing, default)]
294 types_map: std::cell::RefCell<HashMap<String, usize>>,
295}
296
297impl fmt::Debug for Typespace {
298 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
299 f.debug_map()
300 .entries(self.types.iter().map(|t| (t.name().to_string(), t)))
301 .finish()
302 }
303}
304
305impl Typespace {
306 pub fn new() -> Self {
307 Typespace {
308 types: Vec::new(),
309 types_map: std::cell::RefCell::new(HashMap::new()),
310 }
311 }
312
313 pub fn is_empty(&self) -> bool {
314 self.types.is_empty()
315 }
316
317 pub fn types(&self) -> std::slice::Iter<'_, Type> {
318 self.types.iter()
319 }
320
321 pub fn get_type(&self, name: &str) -> Option<&Type> {
322 self.ensure_types_map();
323 let index = {
324 let b = self.types_map.borrow();
325 b.get(name).copied().unwrap_or(usize::MAX)
326 };
327 if index == usize::MAX {
328 return None;
329 }
330 self.types.get(index)
331 }
332
333 pub fn get_type_mut(&mut self, name: &str) -> Option<&mut Type> {
334 self.ensure_types_map();
335 let index = {
336 let b = self.types_map.borrow();
337 b.get(name).copied().unwrap_or(usize::MAX)
338 };
339 if index == usize::MAX {
340 return None;
341 }
342 self.types.get_mut(index)
343 }
344
345 pub fn reserve_type(&mut self, name: &str) -> bool {
346 self.ensure_types_map();
347 if self.types_map.borrow().contains_key(name) {
348 return false;
349 }
350 self.types_map.borrow_mut().insert(name.into(), usize::MAX);
351 true
352 }
353
354 pub fn insert_type(&mut self, ty: Type) {
355 self.ensure_types_map();
356 if let Some(index) = self.types_map.borrow().get(ty.name()) {
357 if index != &usize::MAX {
358 return;
359 }
360 }
361 self.types_map
362 .borrow_mut()
363 .insert(ty.name().into(), self.types.len());
364 self.types.push(ty);
365 }
366
367 pub fn remove_type(&mut self, ty: &str) -> Option<Type> {
368 self.ensure_types_map();
369 let index = self
370 .types_map
371 .borrow()
372 .get(ty)
373 .copied()
374 .unwrap_or(usize::MAX);
375 if index == usize::MAX {
376 return None;
377 }
378
379 self.types_map.borrow_mut().remove(ty);
380 Some(self.types.remove(index))
381 }
382
383 pub fn sort_types(&mut self) {
384 self.types.sort_by(|a, b| a.name().cmp(b.name()));
385 self.build_types_map();
386 }
387
388 pub fn has_type(&self, name: &str) -> bool {
389 self.ensure_types_map();
390 self.types_map.borrow().contains_key(name)
391 }
392
393 pub fn extend(&mut self, other: Self) {
394 self.ensure_types_map();
395 for ty in other.types {
396 if self.has_type(ty.name()) {
397 continue;
398 }
399 self.insert_type(ty);
400 }
401 }
402
403 fn invalidate_types_map(&self) {
404 self.types_map.borrow_mut().clear()
405 }
406
407 fn ensure_types_map(&self) {
408 if self.types_map.borrow().is_empty() && !self.types.is_empty() {
409 self.build_types_map();
410 }
411 }
412
413 fn build_types_map(&self) {
414 let mut types_map = HashMap::new();
415 for (i, ty) in self.types.iter().enumerate() {
416 types_map.insert(ty.name().into(), i);
417 }
418 *(self.types_map.borrow_mut()) = types_map;
419 }
420}
421
422#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
423pub struct Function {
424 #[serde(skip_serializing, default)]
425 pub id: SymbolId,
426
427 pub name: String,
429 pub path: String,
431 #[serde(skip_serializing_if = "String::is_empty", default)]
433 pub description: String,
434 #[serde(skip_serializing_if = "Option::is_none", default)]
437 pub deprecation_note: Option<String>,
438
439 #[serde(skip_serializing_if = "Option::is_none", default)]
440 pub input_type: Option<TypeReference>,
441 #[serde(skip_serializing_if = "Option::is_none", default)]
442 pub input_headers: Option<TypeReference>,
443
444 #[serde(skip_serializing_if = "Option::is_none", default)]
445 pub output_type: Option<TypeReference>,
446
447 #[serde(skip_serializing_if = "Option::is_none", default)]
448 pub error_type: Option<TypeReference>,
449
450 #[serde(skip_serializing_if = "Vec::is_empty", default)]
460 pub serialization: Vec<SerializationMode>,
461
462 #[serde(skip_serializing_if = "is_false", default)]
464 pub readonly: bool,
465
466 #[serde(skip_serializing_if = "BTreeSet::is_empty", default)]
467 pub tags: BTreeSet<String>,
468}
469
470impl Function {
471 pub fn new(name: String) -> Self {
472 let id = SymbolId::endpoint_id(vec![name.clone()]);
473 Function {
474 id,
475 name,
476 deprecation_note: Default::default(),
477 path: Default::default(),
478 description: Default::default(),
479 input_type: None,
480 input_headers: None,
481 output_type: None,
482 error_type: None,
483 serialization: Default::default(),
484 readonly: Default::default(),
485 tags: Default::default(),
486 }
487 }
488
489 pub fn name(&self) -> &str {
490 self.name.as_str()
491 }
492
493 pub fn path(&self) -> &str {
494 self.path.as_str()
495 }
496
497 pub fn description(&self) -> &str {
498 self.description.as_str()
499 }
500
501 pub fn deprecated(&self) -> bool {
502 self.deprecation_note.is_some()
503 }
504
505 pub fn input_type(&self) -> Option<&TypeReference> {
506 self.input_type.as_ref()
507 }
508
509 pub fn input_headers(&self) -> Option<&TypeReference> {
510 self.input_headers.as_ref()
511 }
512
513 pub fn output_type(&self) -> Option<&TypeReference> {
514 self.output_type.as_ref()
515 }
516
517 pub fn error_type(&self) -> Option<&TypeReference> {
518 self.error_type.as_ref()
519 }
520
521 pub fn serialization(&self) -> std::slice::Iter<'_, SerializationMode> {
522 self.serialization.iter()
523 }
524
525 pub fn readonly(&self) -> bool {
526 self.readonly
527 }
528}
529
530#[derive(Debug, Default, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
531#[serde(rename_all = "snake_case")]
532pub enum SerializationMode {
533 #[default]
534 Json,
535 Msgpack,
536}
537
538#[derive(
539 Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq, Hash, PartialOrd, Ord,
540)]
541pub struct TypeReference {
542 pub name: String,
543 #[serde(skip_serializing_if = "Vec::is_empty", default)]
548 pub arguments: Vec<TypeReference>,
549}
550
551impl TypeReference {
552 pub fn new(name: impl Into<String>, arguments: Vec<TypeReference>) -> Self {
553 TypeReference {
554 name: name.into(),
555 arguments,
556 }
557 }
558
559 pub fn name(&self) -> &str {
560 self.name.as_str()
561 }
562
563 pub fn arguments(&self) -> std::slice::Iter<'_, TypeReference> {
564 self.arguments.iter()
565 }
566
567 pub fn fallback_recursively(&mut self, schema: &Typespace) {
568 loop {
569 let Some(type_def) = schema.get_type(self.name()) else {
570 return;
571 };
572 let Some(fallback_type_ref) = type_def.fallback_internal(self) else {
573 return;
574 };
575 *self = fallback_type_ref;
576 }
577 }
578
579 pub fn fallback_once(&self, schema: &Typespace) -> Option<TypeReference> {
580 let type_def = schema.get_type(self.name())?;
581 type_def.fallback_internal(self)
582 }
583}
584
585impl From<&str> for TypeReference {
586 fn from(name: &str) -> Self {
587 TypeReference::new(name, Vec::new())
588 }
589}
590
591impl From<String> for TypeReference {
592 fn from(name: String) -> Self {
593 TypeReference::new(name, Vec::new())
594 }
595}
596
597#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
598pub struct TypeParameter {
599 pub name: String,
600 #[serde(skip_serializing_if = "String::is_empty", default)]
601 pub description: String,
602}
603
604impl TypeParameter {
605 pub fn new(name: String, description: String) -> Self {
606 TypeParameter { name, description }
607 }
608
609 pub fn name(&self) -> &str {
610 self.name.as_str()
611 }
612
613 pub fn description(&self) -> &str {
614 self.description.as_str()
615 }
616}
617
618impl From<&str> for TypeParameter {
619 fn from(name: &str) -> Self {
620 TypeParameter {
621 name: name.into(),
622 description: String::new(),
623 }
624 }
625}
626
627impl From<String> for TypeParameter {
628 fn from(name: String) -> Self {
629 TypeParameter {
630 name,
631 description: String::new(),
632 }
633 }
634}
635
636impl PartialEq for TypeParameter {
637 fn eq(&self, other: &Self) -> bool {
638 self.name == other.name
639 }
640}
641
642impl Eq for TypeParameter {}
643
644impl std::hash::Hash for TypeParameter {
645 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
646 self.name.hash(state);
647 }
648}
649
650#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Eq, PartialEq)]
651#[serde(rename_all = "snake_case", tag = "kind")]
652pub enum Type {
653 Primitive(Primitive),
654 Struct(Struct),
655 Enum(Enum),
656}
657
658impl Type {
659 pub fn name(&self) -> &str {
660 match self {
661 Type::Primitive(p) => &p.name,
662 Type::Struct(s) => &s.name,
663 Type::Enum(e) => &e.name,
664 }
665 }
666
667 pub fn serde_name(&self) -> &str {
668 match self {
669 Type::Primitive(_) => self.name(),
670 Type::Struct(s) => s.serde_name(),
671 Type::Enum(e) => e.serde_name(),
672 }
673 }
674
675 pub fn description(&self) -> &str {
676 match self {
677 Type::Primitive(p) => &p.description,
678 Type::Struct(s) => &s.description,
679 Type::Enum(e) => &e.description,
680 }
681 }
682
683 pub fn parameters(&self) -> std::slice::Iter<'_, TypeParameter> {
684 match self {
685 Type::Primitive(p) => p.parameters(),
686 Type::Struct(s) => s.parameters(),
687 Type::Enum(e) => e.parameters(),
688 }
689 }
690
691 pub fn as_struct(&self) -> Option<&Struct> {
692 match self {
693 Type::Struct(s) => Some(s),
694 _ => None,
695 }
696 }
697
698 pub fn is_struct(&self) -> bool {
699 matches!(self, Type::Struct(_))
700 }
701
702 pub fn as_enum(&self) -> Option<&Enum> {
703 match self {
704 Type::Enum(e) => Some(e),
705 _ => None,
706 }
707 }
708
709 pub fn is_enum(&self) -> bool {
710 matches!(self, Type::Enum(_))
711 }
712
713 pub fn as_primitive(&self) -> Option<&Primitive> {
714 match self {
715 Type::Primitive(p) => Some(p),
716 _ => None,
717 }
718 }
719
720 pub fn is_primitive(&self) -> bool {
721 matches!(self, Type::Primitive(_))
722 }
723
724 fn fallback_internal(&self, origin: &TypeReference) -> Option<TypeReference> {
725 match self {
726 Type::Primitive(p) => p.fallback_internal(origin),
727 Type::Struct(_) => None,
728 Type::Enum(_) => None,
729 }
730 }
731
732 pub fn __internal_rename_current(&mut self, new_name: String) {
733 match self {
734 Type::Primitive(p) => p.name = new_name,
735 Type::Struct(s) => s.name = new_name,
736 Type::Enum(e) => e.name = new_name,
737 }
738 }
739
740 pub fn __internal_rebind_generic_parameters(
741 &mut self,
742 unresolved_to_resolved_map: &std::collections::HashMap<TypeReference, TypeReference>,
743 schema: &Typespace,
744 ) {
745 internal::replace_type_references_for_type(self, unresolved_to_resolved_map, schema)
746 }
747}
748
749#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Eq)]
750pub struct Primitive {
751 #[serde(skip_serializing, default)]
752 pub id: SymbolId,
753
754 pub name: String,
755 #[serde(skip_serializing_if = "String::is_empty", default)]
756 pub description: String,
757
758 #[serde(skip_serializing_if = "Vec::is_empty", default)]
760 pub parameters: Vec<TypeParameter>,
761
762 #[serde(skip_serializing_if = "Option::is_none", default)]
764 pub fallback: Option<TypeReference>,
765}
766
767impl Primitive {
768 pub fn new(
769 name: String,
770 description: String,
771 parameters: Vec<TypeParameter>,
772 fallback: Option<TypeReference>,
773 ) -> Self {
774 let id = SymbolId::new(SymbolKind::Primitive, vec![name.clone()]);
775 Primitive {
776 id,
777 name,
778 description,
779 parameters,
780 fallback,
781 }
782 }
783
784 pub fn name(&self) -> &str {
785 self.name.as_str()
786 }
787
788 pub fn description(&self) -> &str {
789 self.description.as_str()
790 }
791
792 pub fn parameters(&self) -> std::slice::Iter<'_, TypeParameter> {
793 self.parameters.iter()
794 }
795
796 pub fn fallback(&self) -> Option<&TypeReference> {
797 self.fallback.as_ref()
798 }
799
800 fn fallback_internal(&self, origin: &TypeReference) -> Option<TypeReference> {
801 let fallback = self.fallback.as_ref()?;
807
808 if let Some((type_def_param_index, _)) = self
809 .parameters()
810 .enumerate()
811 .find(|(_, type_def_param)| type_def_param.name() == fallback.name())
812 {
813 let Some(origin_type_ref_param) = origin.arguments.get(type_def_param_index) else {
816 return None;
820 };
821 return Some(TypeReference {
822 name: origin_type_ref_param.name.clone(),
823 arguments: origin_type_ref_param.arguments.clone(),
824 });
825 }
826
827 let mut new_arguments_for_origin = Vec::new();
828 for fallback_type_ref_param in fallback.arguments() {
829 let Some((type_def_param_index, _)) =
830 self.parameters().enumerate().find(|(_, type_def_param)| {
831 type_def_param.name() == fallback_type_ref_param.name()
832 })
833 else {
834 continue;
838 };
839
840 let Some(origin_type_ref_param) = origin.arguments.get(type_def_param_index) else {
842 return None;
846 };
847 new_arguments_for_origin.push(origin_type_ref_param.clone());
848 }
849
850 Some(TypeReference {
851 name: fallback.name.clone(),
852 arguments: new_arguments_for_origin,
853 })
854 }
855}
856
857impl PartialEq for Primitive {
858 fn eq(&self, other: &Self) -> bool {
859 self.name == other.name
860 && self.description == other.description
861 && self.parameters == other.parameters
862 && self.fallback == other.fallback
863 }
864}
865
866impl std::hash::Hash for Primitive {
867 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
868 self.name.hash(state);
869 self.description.hash(state);
870 self.parameters.hash(state);
871 self.fallback.hash(state);
872 }
873}
874
875impl From<Primitive> for Type {
876 fn from(val: Primitive) -> Self {
877 Type::Primitive(val)
878 }
879}
880
881#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Eq)]
882pub struct Struct {
883 #[serde(skip_serializing, default)]
884 pub id: SymbolId,
885
886 pub name: String,
888
889 #[serde(skip_serializing_if = "String::is_empty", default)]
892 pub serde_name: String,
893
894 #[serde(skip_serializing_if = "String::is_empty", default)]
896 pub description: String,
897
898 #[serde(skip_serializing_if = "Vec::is_empty", default)]
900 pub parameters: Vec<TypeParameter>,
901
902 pub fields: Fields,
903
904 #[serde(skip_serializing_if = "is_false", default)]
906 pub transparent: bool,
907
908 #[serde(skip_serializing_if = "is_default", default)]
909 pub codegen_config: LanguageSpecificTypeCodegenConfig,
910}
911
912impl Struct {
913 pub fn new(name: impl Into<String>) -> Self {
914 let name = name.into();
915 let id = SymbolId::struct_id(vec![name.clone()]);
916 Struct {
917 id,
918 name,
919 serde_name: Default::default(),
920 description: Default::default(),
921 parameters: Default::default(),
922 fields: Default::default(),
923 transparent: Default::default(),
924 codegen_config: Default::default(),
925 }
926 }
927
928 pub fn name(&self) -> &str {
930 self.name.as_str()
931 }
932
933 pub fn serde_name(&self) -> &str {
935 if self.serde_name.is_empty() {
936 self.name.as_str()
937 } else {
938 self.serde_name.as_str()
939 }
940 }
941
942 pub fn description(&self) -> &str {
943 self.description.as_str()
944 }
945
946 pub fn parameters(&self) -> std::slice::Iter<'_, TypeParameter> {
947 self.parameters.iter()
948 }
949
950 pub fn fields(&self) -> std::slice::Iter<'_, Field> {
951 self.fields.iter()
952 }
953
954 pub fn transparent(&self) -> bool {
955 self.transparent
956 }
957
958 pub fn is_alias(&self) -> bool {
961 self.fields.len() == 1 && (self.fields[0].name() == "0" || self.transparent)
962 }
963
964 pub fn is_unit(&self) -> bool {
968 let Some(first_field) = self.fields.iter().next() else {
969 return false;
970 };
971
972 self.fields.len() == 1
973 && first_field.name() == "0"
974 && first_field.type_ref.name == "std::tuple::Tuple0"
975 && !first_field.required
976 }
977
978 pub fn is_tuple(&self) -> bool {
980 !self.fields.is_empty()
981 && self
982 .fields
983 .iter()
984 .all(|f| f.name().parse::<usize>().is_ok())
985 }
986}
987
988impl PartialEq for Struct {
989 fn eq(&self, other: &Self) -> bool {
990 self.name == other.name
991 && self.serde_name == other.serde_name
992 && self.description == other.description
993 && self.parameters == other.parameters
994 && self.fields == other.fields
995 && self.transparent == other.transparent
996 && self.codegen_config == other.codegen_config
997 }
998}
999
1000impl From<Struct> for Type {
1001 fn from(val: Struct) -> Self {
1002 Type::Struct(val)
1003 }
1004}
1005
1006#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Eq, PartialEq, Default)]
1007#[serde(rename_all = "snake_case")]
1008pub enum Fields {
1009 Named(Vec<Field>),
1013 Unnamed(Vec<Field>),
1017 #[default]
1022 None,
1023}
1024
1025impl Fields {
1026 pub fn is_empty(&self) -> bool {
1027 match self {
1028 Fields::Named(fields) | Fields::Unnamed(fields) => fields.is_empty(),
1029 Fields::None => true,
1030 }
1031 }
1032
1033 pub fn len(&self) -> usize {
1034 match self {
1035 Fields::Named(fields) | Fields::Unnamed(fields) => fields.len(),
1036 Fields::None => 0,
1037 }
1038 }
1039
1040 pub fn iter(&self) -> std::slice::Iter<'_, Field> {
1041 match self {
1042 Fields::Named(fields) | Fields::Unnamed(fields) => fields.iter(),
1043 Fields::None => [].iter(),
1044 }
1045 }
1046
1047 pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, Field> {
1048 match self {
1049 Fields::Named(fields) | Fields::Unnamed(fields) => fields.iter_mut(),
1050 Fields::None => [].iter_mut(),
1051 }
1052 }
1053}
1054
1055impl Index<usize> for Fields {
1056 type Output = Field;
1057
1058 fn index(&self, index: usize) -> &Self::Output {
1059 match self {
1060 Fields::Named(fields) | Fields::Unnamed(fields) => &fields[index],
1061 Fields::None => panic!("index out of bounds"),
1062 }
1063 }
1064}
1065
1066impl IntoIterator for Fields {
1067 type Item = Field;
1068 type IntoIter = std::vec::IntoIter<Field>;
1069
1070 fn into_iter(self) -> Self::IntoIter {
1071 match self {
1072 Fields::Named(fields) => fields.into_iter(),
1073 Fields::Unnamed(fields) => fields.into_iter(),
1074 Fields::None => vec![].into_iter(),
1075 }
1076 }
1077}
1078
1079#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Eq)]
1080pub struct Field {
1081 #[serde(skip_serializing, default)]
1082 pub id: SymbolId,
1083
1084 pub name: String,
1086 #[serde(skip_serializing_if = "String::is_empty", default)]
1089 pub serde_name: String,
1090 #[serde(skip_serializing_if = "String::is_empty", default)]
1092 pub description: String,
1093
1094 #[serde(skip_serializing_if = "Option::is_none", default)]
1097 pub deprecation_note: Option<String>,
1098
1099 #[serde(rename = "type")]
1101 pub type_ref: TypeReference,
1102 #[serde(skip_serializing_if = "is_false", default)]
1121 pub required: bool,
1122 #[serde(skip_serializing_if = "is_false", default)]
1125 pub flattened: bool,
1126
1127 #[serde(skip, default)]
1128 pub transform_callback: String,
1129 #[serde(skip, default)]
1130 pub transform_callback_fn: Option<fn(&mut TypeReference, &Typespace) -> ()>,
1131}
1132
1133impl PartialEq for Field {
1134 fn eq(
1135 &self,
1136 Self {
1137 id: _,
1138 name,
1139 serde_name,
1140 description,
1141 deprecation_note,
1142 type_ref,
1143 required,
1144 flattened,
1145 transform_callback,
1146 transform_callback_fn: _,
1147 }: &Self,
1148 ) -> bool {
1149 self.name == *name
1150 && self.serde_name == *serde_name
1151 && self.description == *description
1152 && self.deprecation_note == *deprecation_note
1153 && self.type_ref == *type_ref
1154 && self.required == *required
1155 && self.flattened == *flattened
1156 && self.transform_callback == *transform_callback
1157 }
1158}
1159
1160impl std::hash::Hash for Field {
1161 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1162 self.name.hash(state);
1163 self.serde_name.hash(state);
1164 self.description.hash(state);
1165 self.deprecation_note.hash(state);
1166 self.type_ref.hash(state);
1167 self.required.hash(state);
1168 self.flattened.hash(state);
1169 self.transform_callback.hash(state);
1170 }
1171}
1172
1173impl Field {
1174 pub fn new(name: String, type_ref: TypeReference) -> Self {
1175 Field {
1176 id: SymbolId::default(),
1177 name,
1178 type_ref,
1179 serde_name: Default::default(),
1180 description: Default::default(),
1181 deprecation_note: Default::default(),
1182 required: Default::default(),
1183 flattened: Default::default(),
1184 transform_callback: Default::default(),
1185 transform_callback_fn: Default::default(),
1186 }
1187 }
1188
1189 pub fn with_required(mut self, required: bool) -> Self {
1190 self.required = required;
1191 self
1192 }
1193
1194 pub fn name(&self) -> &str {
1195 self.name.as_str()
1196 }
1197
1198 pub fn is_named(&self) -> bool {
1199 !self.is_unnamed()
1200 }
1201
1202 pub fn is_unnamed(&self) -> bool {
1203 self.name.parse::<u64>().is_ok()
1204 }
1205
1206 pub fn serde_name(&self) -> &str {
1207 if self.serde_name.is_empty() {
1208 self.name.as_str()
1209 } else {
1210 self.serde_name.as_str()
1211 }
1212 }
1213
1214 pub fn description(&self) -> &str {
1215 self.description.as_str()
1216 }
1217
1218 pub fn deprecated(&self) -> bool {
1219 self.deprecation_note.is_some()
1220 }
1221
1222 pub fn type_ref(&self) -> &TypeReference {
1223 &self.type_ref
1224 }
1225
1226 pub fn required(&self) -> bool {
1227 self.required
1228 }
1229
1230 pub fn flattened(&self) -> bool {
1231 self.flattened
1232 }
1233
1234 pub fn transform_callback(&self) -> &str {
1235 self.transform_callback.as_str()
1236 }
1237
1238 pub fn transform_callback_fn(&self) -> Option<fn(&mut TypeReference, &Typespace)> {
1239 self.transform_callback_fn
1240 }
1241}
1242
1243fn is_false(b: &bool) -> bool {
1244 !*b
1245}
1246
1247fn is_default<T: Default + PartialEq>(t: &T) -> bool {
1248 *t == Default::default()
1249}
1250
1251#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Eq)]
1252pub struct Enum {
1253 #[serde(skip_serializing, default)]
1254 pub id: SymbolId,
1255
1256 pub name: String,
1257 #[serde(skip_serializing_if = "String::is_empty", default)]
1258 pub serde_name: String,
1259 #[serde(skip_serializing_if = "String::is_empty", default)]
1260 pub description: String,
1261
1262 #[serde(skip_serializing_if = "Vec::is_empty", default)]
1264 pub parameters: Vec<TypeParameter>,
1265
1266 #[serde(skip_serializing_if = "Representation::is_default", default)]
1267 pub representation: Representation,
1268
1269 #[serde(skip_serializing_if = "Vec::is_empty", default)]
1270 pub variants: Vec<Variant>,
1271
1272 #[serde(skip_serializing_if = "is_default", default)]
1273 pub codegen_config: LanguageSpecificTypeCodegenConfig,
1274}
1275
1276impl Enum {
1277 pub fn new(name: String) -> Self {
1278 let id = SymbolId::enum_id(vec![name.clone()]);
1279 Enum {
1280 id,
1281 name,
1282 serde_name: Default::default(),
1283 description: Default::default(),
1284 parameters: Default::default(),
1285 representation: Default::default(),
1286 variants: Default::default(),
1287 codegen_config: Default::default(),
1288 }
1289 }
1290
1291 pub fn name(&self) -> &str {
1292 self.name.as_str()
1293 }
1294
1295 pub fn serde_name(&self) -> &str {
1296 if self.serde_name.is_empty() {
1297 self.name.as_str()
1298 } else {
1299 self.serde_name.as_str()
1300 }
1301 }
1302
1303 pub fn description(&self) -> &str {
1304 self.description.as_str()
1305 }
1306
1307 pub fn parameters(&self) -> std::slice::Iter<'_, TypeParameter> {
1308 self.parameters.iter()
1309 }
1310
1311 pub fn representation(&self) -> &Representation {
1312 &self.representation
1313 }
1314
1315 pub fn variants(&self) -> std::slice::Iter<'_, Variant> {
1316 self.variants.iter()
1317 }
1318}
1319
1320impl PartialEq for Enum {
1321 fn eq(&self, other: &Self) -> bool {
1322 self.name == other.name
1323 && self.serde_name == other.serde_name
1324 && self.description == other.description
1325 && self.parameters == other.parameters
1326 && self.representation == other.representation
1327 && self.variants == other.variants
1328 && self.codegen_config == other.codegen_config
1329 }
1330}
1331
1332impl From<Enum> for Type {
1333 fn from(val: Enum) -> Self {
1334 Type::Enum(val)
1335 }
1336}
1337
1338#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Eq)]
1339pub struct Variant {
1340 #[serde(skip_serializing, default)]
1341 pub id: SymbolId,
1342
1343 pub name: String,
1344 #[serde(skip_serializing_if = "String::is_empty", default)]
1345 pub serde_name: String,
1346 #[serde(skip_serializing_if = "String::is_empty", default)]
1347 pub description: String,
1348
1349 pub fields: Fields,
1350 #[serde(skip_serializing_if = "Option::is_none", default)]
1351 pub discriminant: Option<isize>,
1352
1353 #[serde(skip_serializing_if = "is_false", default)]
1355 pub untagged: bool,
1356}
1357
1358impl Variant {
1359 pub fn new(name: String) -> Self {
1360 Variant {
1361 id: SymbolId::default(),
1362 name,
1363 serde_name: String::new(),
1364 description: String::new(),
1365 fields: Fields::None,
1366 discriminant: None,
1367 untagged: false,
1368 }
1369 }
1370
1371 pub fn name(&self) -> &str {
1372 self.name.as_str()
1373 }
1374
1375 pub fn serde_name(&self) -> &str {
1376 if self.serde_name.is_empty() {
1377 self.name.as_str()
1378 } else {
1379 self.serde_name.as_str()
1380 }
1381 }
1382
1383 pub fn description(&self) -> &str {
1384 self.description.as_str()
1385 }
1386
1387 pub fn fields(&self) -> std::slice::Iter<'_, Field> {
1388 self.fields.iter()
1389 }
1390
1391 pub fn discriminant(&self) -> Option<isize> {
1392 self.discriminant
1393 }
1394
1395 pub fn untagged(&self) -> bool {
1396 self.untagged
1397 }
1398}
1399
1400impl PartialEq for Variant {
1401 fn eq(&self, other: &Self) -> bool {
1402 self.name == other.name
1403 && self.serde_name == other.serde_name
1404 && self.description == other.description
1405 && self.fields == other.fields
1406 && self.discriminant == other.discriminant
1407 && self.untagged == other.untagged
1408 }
1409}
1410
1411#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Eq, PartialEq, Hash, Default)]
1412#[serde(rename_all = "snake_case")]
1413pub enum Representation {
1414 #[default]
1420 External,
1421
1422 Internal { tag: String },
1428
1429 Adjacent { tag: String, content: String },
1435
1436 None,
1442}
1443
1444impl Representation {
1445 pub fn new() -> Self {
1446 Default::default()
1447 }
1448
1449 pub fn is_default(&self) -> bool {
1450 matches!(self, Representation::External)
1451 }
1452
1453 pub fn is_external(&self) -> bool {
1454 matches!(self, Representation::External)
1455 }
1456
1457 pub fn is_internal(&self) -> bool {
1458 matches!(self, Representation::Internal { .. })
1459 }
1460
1461 pub fn is_adjacent(&self) -> bool {
1462 matches!(self, Representation::Adjacent { .. })
1463 }
1464
1465 pub fn is_none(&self) -> bool {
1466 matches!(self, Representation::None)
1467 }
1468}