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