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 error_type: Option<TypeReference>,
446
447 #[serde(flatten)]
448 pub output_type: OutputType,
449
450 #[serde(skip_serializing_if = "Vec::is_empty", default)]
459 pub serialization: Vec<SerializationMode>,
460
461 #[serde(skip_serializing_if = "is_false", default)]
463 pub readonly: bool,
464
465 #[serde(skip_serializing_if = "BTreeSet::is_empty", default)]
466 pub tags: BTreeSet<String>,
467}
468
469impl Function {
470 pub fn new(name: String) -> Self {
471 let id = SymbolId::endpoint_id(vec![name.clone()]);
472 Function {
473 id,
474 name,
475 deprecation_note: Default::default(),
476 path: Default::default(),
477 description: Default::default(),
478 input_type: None,
479 input_headers: None,
480 error_type: None,
481 output_type: OutputType::Complete { output_type: None },
482 serialization: Default::default(),
483 readonly: Default::default(),
484 tags: Default::default(),
485 }
486 }
487
488 pub fn name(&self) -> &str {
489 self.name.as_str()
490 }
491
492 pub fn path(&self) -> &str {
493 self.path.as_str()
494 }
495
496 pub fn description(&self) -> &str {
497 self.description.as_str()
498 }
499
500 pub fn deprecated(&self) -> bool {
501 self.deprecation_note.is_some()
502 }
503
504 pub fn input_type(&self) -> Option<&TypeReference> {
505 self.input_type.as_ref()
506 }
507
508 pub fn input_headers(&self) -> Option<&TypeReference> {
509 self.input_headers.as_ref()
510 }
511
512 pub fn output_type(&self) -> &OutputType {
513 &self.output_type
514 }
515
516 pub fn serialization(&self) -> std::slice::Iter<'_, SerializationMode> {
517 self.serialization.iter()
518 }
519
520 pub fn readonly(&self) -> bool {
521 self.readonly
522 }
523}
524
525#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
526#[serde(tag = "output_kind", rename_all = "snake_case")]
527pub enum OutputType {
528 Complete {
529 #[serde(skip_serializing_if = "Option::is_none", default)]
530 output_type: Option<TypeReference>,
531 },
532 Stream {
533 item_type: TypeReference,
534 },
535}
536
537impl OutputType {
538 pub fn type_refs(&self) -> Vec<&TypeReference> {
539 match self {
540 OutputType::Complete {
541 output_type: Some(output_type),
542 } => vec![output_type],
543 OutputType::Complete { output_type: None } => vec![],
544 OutputType::Stream { item_type } => vec![item_type],
545 }
546 }
547}
548
549#[derive(Debug, Default, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
550#[serde(rename_all = "snake_case")]
551pub enum SerializationMode {
552 #[default]
553 Json,
554 Msgpack,
555}
556
557#[derive(
558 Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq, Hash, PartialOrd, Ord,
559)]
560pub struct TypeReference {
561 pub name: String,
562 #[serde(skip_serializing_if = "Vec::is_empty", default)]
567 pub arguments: Vec<TypeReference>,
568}
569
570impl TypeReference {
571 pub fn new(name: impl Into<String>, arguments: Vec<TypeReference>) -> Self {
572 TypeReference {
573 name: name.into(),
574 arguments,
575 }
576 }
577
578 pub fn name(&self) -> &str {
579 self.name.as_str()
580 }
581
582 pub fn arguments(&self) -> std::slice::Iter<'_, TypeReference> {
583 self.arguments.iter()
584 }
585
586 pub fn fallback_recursively(&mut self, schema: &Typespace) {
587 loop {
588 let Some(type_def) = schema.get_type(self.name()) else {
589 return;
590 };
591 let Some(fallback_type_ref) = type_def.fallback_internal(self) else {
592 return;
593 };
594 *self = fallback_type_ref;
595 }
596 }
597
598 pub fn fallback_once(&self, schema: &Typespace) -> Option<TypeReference> {
599 let type_def = schema.get_type(self.name())?;
600 type_def.fallback_internal(self)
601 }
602}
603
604impl From<&str> for TypeReference {
605 fn from(name: &str) -> Self {
606 TypeReference::new(name, Vec::new())
607 }
608}
609
610impl From<String> for TypeReference {
611 fn from(name: String) -> Self {
612 TypeReference::new(name, Vec::new())
613 }
614}
615
616#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
617pub struct TypeParameter {
618 pub name: String,
619 #[serde(skip_serializing_if = "String::is_empty", default)]
620 pub description: String,
621}
622
623impl TypeParameter {
624 pub fn new(name: String, description: String) -> Self {
625 TypeParameter { name, description }
626 }
627
628 pub fn name(&self) -> &str {
629 self.name.as_str()
630 }
631
632 pub fn description(&self) -> &str {
633 self.description.as_str()
634 }
635}
636
637impl From<&str> for TypeParameter {
638 fn from(name: &str) -> Self {
639 TypeParameter {
640 name: name.into(),
641 description: String::new(),
642 }
643 }
644}
645
646impl From<String> for TypeParameter {
647 fn from(name: String) -> Self {
648 TypeParameter {
649 name,
650 description: String::new(),
651 }
652 }
653}
654
655impl PartialEq for TypeParameter {
656 fn eq(&self, other: &Self) -> bool {
657 self.name == other.name
658 }
659}
660
661impl Eq for TypeParameter {}
662
663impl std::hash::Hash for TypeParameter {
664 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
665 self.name.hash(state);
666 }
667}
668
669#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Eq, PartialEq)]
670#[serde(rename_all = "snake_case", tag = "kind")]
671pub enum Type {
672 Primitive(Primitive),
673 Struct(Struct),
674 Enum(Enum),
675}
676
677impl Type {
678 pub fn name(&self) -> &str {
679 match self {
680 Type::Primitive(p) => &p.name,
681 Type::Struct(s) => &s.name,
682 Type::Enum(e) => &e.name,
683 }
684 }
685
686 pub fn serde_name(&self) -> &str {
687 match self {
688 Type::Primitive(_) => self.name(),
689 Type::Struct(s) => s.serde_name(),
690 Type::Enum(e) => e.serde_name(),
691 }
692 }
693
694 pub fn description(&self) -> &str {
695 match self {
696 Type::Primitive(p) => &p.description,
697 Type::Struct(s) => &s.description,
698 Type::Enum(e) => &e.description,
699 }
700 }
701
702 pub fn parameters(&self) -> std::slice::Iter<'_, TypeParameter> {
703 match self {
704 Type::Primitive(p) => p.parameters(),
705 Type::Struct(s) => s.parameters(),
706 Type::Enum(e) => e.parameters(),
707 }
708 }
709
710 pub fn as_struct(&self) -> Option<&Struct> {
711 match self {
712 Type::Struct(s) => Some(s),
713 _ => None,
714 }
715 }
716
717 pub fn is_struct(&self) -> bool {
718 matches!(self, Type::Struct(_))
719 }
720
721 pub fn as_enum(&self) -> Option<&Enum> {
722 match self {
723 Type::Enum(e) => Some(e),
724 _ => None,
725 }
726 }
727
728 pub fn is_enum(&self) -> bool {
729 matches!(self, Type::Enum(_))
730 }
731
732 pub fn as_primitive(&self) -> Option<&Primitive> {
733 match self {
734 Type::Primitive(p) => Some(p),
735 _ => None,
736 }
737 }
738
739 pub fn is_primitive(&self) -> bool {
740 matches!(self, Type::Primitive(_))
741 }
742
743 fn fallback_internal(&self, origin: &TypeReference) -> Option<TypeReference> {
744 match self {
745 Type::Primitive(p) => p.fallback_internal(origin),
746 Type::Struct(_) => None,
747 Type::Enum(_) => None,
748 }
749 }
750
751 pub fn __internal_rename_current(&mut self, new_name: String) {
752 match self {
753 Type::Primitive(p) => p.name = new_name,
754 Type::Struct(s) => s.name = new_name,
755 Type::Enum(e) => e.name = new_name,
756 }
757 }
758
759 pub fn __internal_rebind_generic_parameters(
760 &mut self,
761 unresolved_to_resolved_map: &std::collections::HashMap<TypeReference, TypeReference>,
762 schema: &Typespace,
763 ) {
764 internal::replace_type_references_for_type(self, unresolved_to_resolved_map, schema)
765 }
766}
767
768#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Eq)]
769pub struct Primitive {
770 #[serde(skip_serializing, default)]
771 pub id: SymbolId,
772
773 pub name: String,
774 #[serde(skip_serializing_if = "String::is_empty", default)]
775 pub description: String,
776
777 #[serde(skip_serializing_if = "Vec::is_empty", default)]
779 pub parameters: Vec<TypeParameter>,
780
781 #[serde(skip_serializing_if = "Option::is_none", default)]
783 pub fallback: Option<TypeReference>,
784}
785
786impl Primitive {
787 pub fn new(
788 name: String,
789 description: String,
790 parameters: Vec<TypeParameter>,
791 fallback: Option<TypeReference>,
792 ) -> Self {
793 let id = SymbolId::new(SymbolKind::Primitive, vec![name.clone()]);
794 Primitive {
795 id,
796 name,
797 description,
798 parameters,
799 fallback,
800 }
801 }
802
803 pub fn name(&self) -> &str {
804 self.name.as_str()
805 }
806
807 pub fn description(&self) -> &str {
808 self.description.as_str()
809 }
810
811 pub fn parameters(&self) -> std::slice::Iter<'_, TypeParameter> {
812 self.parameters.iter()
813 }
814
815 pub fn fallback(&self) -> Option<&TypeReference> {
816 self.fallback.as_ref()
817 }
818
819 fn fallback_internal(&self, origin: &TypeReference) -> Option<TypeReference> {
820 let fallback = self.fallback.as_ref()?;
826
827 if let Some((type_def_param_index, _)) = self
828 .parameters()
829 .enumerate()
830 .find(|(_, type_def_param)| type_def_param.name() == fallback.name())
831 {
832 let Some(origin_type_ref_param) = origin.arguments.get(type_def_param_index) else {
835 return None;
839 };
840 return Some(TypeReference {
841 name: origin_type_ref_param.name.clone(),
842 arguments: origin_type_ref_param.arguments.clone(),
843 });
844 }
845
846 let mut new_arguments_for_origin = Vec::new();
847 for fallback_type_ref_param in fallback.arguments() {
848 let Some((type_def_param_index, _)) =
849 self.parameters().enumerate().find(|(_, type_def_param)| {
850 type_def_param.name() == fallback_type_ref_param.name()
851 })
852 else {
853 continue;
857 };
858
859 let Some(origin_type_ref_param) = origin.arguments.get(type_def_param_index) else {
861 return None;
865 };
866 new_arguments_for_origin.push(origin_type_ref_param.clone());
867 }
868
869 Some(TypeReference {
870 name: fallback.name.clone(),
871 arguments: new_arguments_for_origin,
872 })
873 }
874}
875
876impl PartialEq for Primitive {
877 fn eq(&self, other: &Self) -> bool {
878 self.name == other.name
879 && self.description == other.description
880 && self.parameters == other.parameters
881 && self.fallback == other.fallback
882 }
883}
884
885impl std::hash::Hash for Primitive {
886 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
887 self.name.hash(state);
888 self.description.hash(state);
889 self.parameters.hash(state);
890 self.fallback.hash(state);
891 }
892}
893
894impl From<Primitive> for Type {
895 fn from(val: Primitive) -> Self {
896 Type::Primitive(val)
897 }
898}
899
900#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Eq)]
901pub struct Struct {
902 #[serde(skip_serializing, default)]
903 pub id: SymbolId,
904
905 pub name: String,
907
908 #[serde(skip_serializing_if = "String::is_empty", default)]
911 pub serde_name: String,
912
913 #[serde(skip_serializing_if = "String::is_empty", default)]
915 pub description: String,
916
917 #[serde(skip_serializing_if = "Vec::is_empty", default)]
919 pub parameters: Vec<TypeParameter>,
920
921 pub fields: Fields,
922
923 #[serde(skip_serializing_if = "is_false", default)]
925 pub transparent: bool,
926
927 #[serde(skip_serializing_if = "is_default", default)]
928 pub codegen_config: LanguageSpecificTypeCodegenConfig,
929}
930
931impl Struct {
932 pub fn new(name: impl Into<String>) -> Self {
933 let name = name.into();
934 let id = SymbolId::struct_id(vec![name.clone()]);
935 Struct {
936 id,
937 name,
938 serde_name: Default::default(),
939 description: Default::default(),
940 parameters: Default::default(),
941 fields: Default::default(),
942 transparent: Default::default(),
943 codegen_config: Default::default(),
944 }
945 }
946
947 pub fn name(&self) -> &str {
949 self.name.as_str()
950 }
951
952 pub fn serde_name(&self) -> &str {
954 if self.serde_name.is_empty() {
955 self.name.as_str()
956 } else {
957 self.serde_name.as_str()
958 }
959 }
960
961 pub fn description(&self) -> &str {
962 self.description.as_str()
963 }
964
965 pub fn parameters(&self) -> std::slice::Iter<'_, TypeParameter> {
966 self.parameters.iter()
967 }
968
969 pub fn fields(&self) -> std::slice::Iter<'_, Field> {
970 self.fields.iter()
971 }
972
973 pub fn transparent(&self) -> bool {
974 self.transparent
975 }
976
977 pub fn is_alias(&self) -> bool {
980 self.fields.len() == 1 && (self.fields[0].name() == "0" || self.transparent)
981 }
982
983 pub fn is_unit(&self) -> bool {
987 let Some(first_field) = self.fields.iter().next() else {
988 return false;
989 };
990
991 self.fields.len() == 1
992 && first_field.name() == "0"
993 && first_field.type_ref.name == "std::tuple::Tuple0"
994 && !first_field.required
995 }
996
997 pub fn is_tuple(&self) -> bool {
999 !self.fields.is_empty()
1000 && self
1001 .fields
1002 .iter()
1003 .all(|f| f.name().parse::<usize>().is_ok())
1004 }
1005}
1006
1007impl PartialEq for Struct {
1008 fn eq(&self, other: &Self) -> bool {
1009 self.name == other.name
1010 && self.serde_name == other.serde_name
1011 && self.description == other.description
1012 && self.parameters == other.parameters
1013 && self.fields == other.fields
1014 && self.transparent == other.transparent
1015 && self.codegen_config == other.codegen_config
1016 }
1017}
1018
1019impl From<Struct> for Type {
1020 fn from(val: Struct) -> Self {
1021 Type::Struct(val)
1022 }
1023}
1024
1025#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Eq, PartialEq, Default)]
1026#[serde(rename_all = "snake_case")]
1027pub enum Fields {
1028 Named(Vec<Field>),
1032 Unnamed(Vec<Field>),
1036 #[default]
1041 None,
1042}
1043
1044impl Fields {
1045 pub fn is_empty(&self) -> bool {
1046 match self {
1047 Fields::Named(fields) | Fields::Unnamed(fields) => fields.is_empty(),
1048 Fields::None => true,
1049 }
1050 }
1051
1052 pub fn len(&self) -> usize {
1053 match self {
1054 Fields::Named(fields) | Fields::Unnamed(fields) => fields.len(),
1055 Fields::None => 0,
1056 }
1057 }
1058
1059 pub fn iter(&self) -> std::slice::Iter<'_, Field> {
1060 match self {
1061 Fields::Named(fields) | Fields::Unnamed(fields) => fields.iter(),
1062 Fields::None => [].iter(),
1063 }
1064 }
1065
1066 pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, Field> {
1067 match self {
1068 Fields::Named(fields) | Fields::Unnamed(fields) => fields.iter_mut(),
1069 Fields::None => [].iter_mut(),
1070 }
1071 }
1072}
1073
1074impl Index<usize> for Fields {
1075 type Output = Field;
1076
1077 fn index(&self, index: usize) -> &Self::Output {
1078 match self {
1079 Fields::Named(fields) | Fields::Unnamed(fields) => &fields[index],
1080 Fields::None => panic!("index out of bounds"),
1081 }
1082 }
1083}
1084
1085impl IntoIterator for Fields {
1086 type Item = Field;
1087 type IntoIter = std::vec::IntoIter<Field>;
1088
1089 fn into_iter(self) -> Self::IntoIter {
1090 match self {
1091 Fields::Named(fields) => fields.into_iter(),
1092 Fields::Unnamed(fields) => fields.into_iter(),
1093 Fields::None => vec![].into_iter(),
1094 }
1095 }
1096}
1097
1098#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Eq)]
1099pub struct Field {
1100 #[serde(skip_serializing, default)]
1101 pub id: SymbolId,
1102
1103 pub name: String,
1105 #[serde(skip_serializing_if = "String::is_empty", default)]
1108 pub serde_name: String,
1109 #[serde(skip_serializing_if = "String::is_empty", default)]
1111 pub description: String,
1112
1113 #[serde(skip_serializing_if = "Option::is_none", default)]
1116 pub deprecation_note: Option<String>,
1117
1118 #[serde(rename = "type")]
1120 pub type_ref: TypeReference,
1121 #[serde(skip_serializing_if = "is_false", default)]
1140 pub required: bool,
1141 #[serde(skip_serializing_if = "is_false", default)]
1144 pub flattened: bool,
1145
1146 #[serde(skip, default)]
1147 pub transform_callback: String,
1148 #[serde(skip, default)]
1149 pub transform_callback_fn: Option<fn(&mut TypeReference, &Typespace) -> ()>,
1150}
1151
1152impl PartialEq for Field {
1153 fn eq(
1154 &self,
1155 Self {
1156 id: _,
1157 name,
1158 serde_name,
1159 description,
1160 deprecation_note,
1161 type_ref,
1162 required,
1163 flattened,
1164 transform_callback,
1165 transform_callback_fn: _,
1166 }: &Self,
1167 ) -> bool {
1168 self.name == *name
1169 && self.serde_name == *serde_name
1170 && self.description == *description
1171 && self.deprecation_note == *deprecation_note
1172 && self.type_ref == *type_ref
1173 && self.required == *required
1174 && self.flattened == *flattened
1175 && self.transform_callback == *transform_callback
1176 }
1177}
1178
1179impl std::hash::Hash for Field {
1180 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1181 self.name.hash(state);
1182 self.serde_name.hash(state);
1183 self.description.hash(state);
1184 self.deprecation_note.hash(state);
1185 self.type_ref.hash(state);
1186 self.required.hash(state);
1187 self.flattened.hash(state);
1188 self.transform_callback.hash(state);
1189 }
1190}
1191
1192impl Field {
1193 pub fn new(name: String, type_ref: TypeReference) -> Self {
1194 Field {
1195 id: SymbolId::default(),
1196 name,
1197 type_ref,
1198 serde_name: Default::default(),
1199 description: Default::default(),
1200 deprecation_note: Default::default(),
1201 required: Default::default(),
1202 flattened: Default::default(),
1203 transform_callback: Default::default(),
1204 transform_callback_fn: Default::default(),
1205 }
1206 }
1207
1208 pub fn with_required(mut self, required: bool) -> Self {
1209 self.required = required;
1210 self
1211 }
1212
1213 pub fn name(&self) -> &str {
1214 self.name.as_str()
1215 }
1216
1217 pub fn is_named(&self) -> bool {
1218 !self.is_unnamed()
1219 }
1220
1221 pub fn is_unnamed(&self) -> bool {
1222 self.name.parse::<u64>().is_ok()
1223 }
1224
1225 pub fn serde_name(&self) -> &str {
1226 if self.serde_name.is_empty() {
1227 self.name.as_str()
1228 } else {
1229 self.serde_name.as_str()
1230 }
1231 }
1232
1233 pub fn description(&self) -> &str {
1234 self.description.as_str()
1235 }
1236
1237 pub fn deprecated(&self) -> bool {
1238 self.deprecation_note.is_some()
1239 }
1240
1241 pub fn type_ref(&self) -> &TypeReference {
1242 &self.type_ref
1243 }
1244
1245 pub fn required(&self) -> bool {
1246 self.required
1247 }
1248
1249 pub fn flattened(&self) -> bool {
1250 self.flattened
1251 }
1252
1253 pub fn transform_callback(&self) -> &str {
1254 self.transform_callback.as_str()
1255 }
1256
1257 pub fn transform_callback_fn(&self) -> Option<fn(&mut TypeReference, &Typespace)> {
1258 self.transform_callback_fn
1259 }
1260}
1261
1262fn is_false(b: &bool) -> bool {
1263 !*b
1264}
1265
1266fn is_default<T: Default + PartialEq>(t: &T) -> bool {
1267 *t == Default::default()
1268}
1269
1270#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Eq)]
1271pub struct Enum {
1272 #[serde(skip_serializing, default)]
1273 pub id: SymbolId,
1274
1275 pub name: String,
1276 #[serde(skip_serializing_if = "String::is_empty", default)]
1277 pub serde_name: String,
1278 #[serde(skip_serializing_if = "String::is_empty", default)]
1279 pub description: String,
1280
1281 #[serde(skip_serializing_if = "Vec::is_empty", default)]
1283 pub parameters: Vec<TypeParameter>,
1284
1285 #[serde(skip_serializing_if = "Representation::is_default", default)]
1286 pub representation: Representation,
1287
1288 #[serde(skip_serializing_if = "Vec::is_empty", default)]
1289 pub variants: Vec<Variant>,
1290
1291 #[serde(skip_serializing_if = "is_default", default)]
1292 pub codegen_config: LanguageSpecificTypeCodegenConfig,
1293}
1294
1295impl Enum {
1296 pub fn new(name: String) -> Self {
1297 let id = SymbolId::enum_id(vec![name.clone()]);
1298 Enum {
1299 id,
1300 name,
1301 serde_name: Default::default(),
1302 description: Default::default(),
1303 parameters: Default::default(),
1304 representation: Default::default(),
1305 variants: Default::default(),
1306 codegen_config: Default::default(),
1307 }
1308 }
1309
1310 pub fn name(&self) -> &str {
1311 self.name.as_str()
1312 }
1313
1314 pub fn serde_name(&self) -> &str {
1315 if self.serde_name.is_empty() {
1316 self.name.as_str()
1317 } else {
1318 self.serde_name.as_str()
1319 }
1320 }
1321
1322 pub fn description(&self) -> &str {
1323 self.description.as_str()
1324 }
1325
1326 pub fn parameters(&self) -> std::slice::Iter<'_, TypeParameter> {
1327 self.parameters.iter()
1328 }
1329
1330 pub fn representation(&self) -> &Representation {
1331 &self.representation
1332 }
1333
1334 pub fn variants(&self) -> std::slice::Iter<'_, Variant> {
1335 self.variants.iter()
1336 }
1337}
1338
1339impl PartialEq for Enum {
1340 fn eq(&self, other: &Self) -> bool {
1341 self.name == other.name
1342 && self.serde_name == other.serde_name
1343 && self.description == other.description
1344 && self.parameters == other.parameters
1345 && self.representation == other.representation
1346 && self.variants == other.variants
1347 && self.codegen_config == other.codegen_config
1348 }
1349}
1350
1351impl From<Enum> for Type {
1352 fn from(val: Enum) -> Self {
1353 Type::Enum(val)
1354 }
1355}
1356
1357#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Eq)]
1358pub struct Variant {
1359 #[serde(skip_serializing, default)]
1360 pub id: SymbolId,
1361
1362 pub name: String,
1363 #[serde(skip_serializing_if = "String::is_empty", default)]
1364 pub serde_name: String,
1365 #[serde(skip_serializing_if = "String::is_empty", default)]
1366 pub description: String,
1367
1368 pub fields: Fields,
1369 #[serde(skip_serializing_if = "Option::is_none", default)]
1370 pub discriminant: Option<isize>,
1371
1372 #[serde(skip_serializing_if = "is_false", default)]
1374 pub untagged: bool,
1375}
1376
1377impl Variant {
1378 pub fn new(name: String) -> Self {
1379 Variant {
1380 id: SymbolId::default(),
1381 name,
1382 serde_name: String::new(),
1383 description: String::new(),
1384 fields: Fields::None,
1385 discriminant: None,
1386 untagged: false,
1387 }
1388 }
1389
1390 pub fn name(&self) -> &str {
1391 self.name.as_str()
1392 }
1393
1394 pub fn serde_name(&self) -> &str {
1395 if self.serde_name.is_empty() {
1396 self.name.as_str()
1397 } else {
1398 self.serde_name.as_str()
1399 }
1400 }
1401
1402 pub fn description(&self) -> &str {
1403 self.description.as_str()
1404 }
1405
1406 pub fn fields(&self) -> std::slice::Iter<'_, Field> {
1407 self.fields.iter()
1408 }
1409
1410 pub fn discriminant(&self) -> Option<isize> {
1411 self.discriminant
1412 }
1413
1414 pub fn untagged(&self) -> bool {
1415 self.untagged
1416 }
1417}
1418
1419impl PartialEq for Variant {
1420 fn eq(&self, other: &Self) -> bool {
1421 self.name == other.name
1422 && self.serde_name == other.serde_name
1423 && self.description == other.description
1424 && self.fields == other.fields
1425 && self.discriminant == other.discriminant
1426 && self.untagged == other.untagged
1427 }
1428}
1429
1430#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Eq, PartialEq, Hash, Default)]
1431#[serde(rename_all = "snake_case")]
1432pub enum Representation {
1433 #[default]
1439 External,
1440
1441 Internal { tag: String },
1447
1448 Adjacent { tag: String, content: String },
1454
1455 None,
1461}
1462
1463impl Representation {
1464 pub fn new() -> Self {
1465 Default::default()
1466 }
1467
1468 pub fn is_default(&self) -> bool {
1469 matches!(self, Representation::External)
1470 }
1471
1472 pub fn is_external(&self) -> bool {
1473 matches!(self, Representation::External)
1474 }
1475
1476 pub fn is_internal(&self) -> bool {
1477 matches!(self, Representation::Internal { .. })
1478 }
1479
1480 pub fn is_adjacent(&self) -> bool {
1481 matches!(self, Representation::Adjacent { .. })
1482 }
1483
1484 pub fn is_none(&self) -> bool {
1485 matches!(self, Representation::None)
1486 }
1487}