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 pub fn retain<F>(&mut self, mut predicate: F)
1029 where
1030 F: FnMut(&Field) -> bool,
1031 {
1032 match self {
1033 Fields::Named(fields) | Fields::Unnamed(fields) => fields.retain(|f| predicate(f)),
1034 Fields::None => {}
1035 }
1036 }
1037}
1038
1039impl Index<usize> for Fields {
1040 type Output = Field;
1041
1042 fn index(&self, index: usize) -> &Self::Output {
1043 match self {
1044 Fields::Named(fields) | Fields::Unnamed(fields) => &fields[index],
1045 Fields::None => panic!("index out of bounds"),
1046 }
1047 }
1048}
1049
1050impl IntoIterator for Fields {
1051 type Item = Field;
1052 type IntoIter = std::vec::IntoIter<Field>;
1053
1054 fn into_iter(self) -> Self::IntoIter {
1055 match self {
1056 Fields::Named(fields) => fields.into_iter(),
1057 Fields::Unnamed(fields) => fields.into_iter(),
1058 Fields::None => vec![].into_iter(),
1059 }
1060 }
1061}
1062
1063#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Eq)]
1064pub struct Field {
1065 pub name: String,
1067 #[serde(skip_serializing_if = "String::is_empty", default)]
1070 pub serde_name: String,
1071 #[serde(skip_serializing_if = "String::is_empty", default)]
1073 pub description: String,
1074
1075 #[serde(skip_serializing_if = "Option::is_none", default)]
1078 pub deprecation_note: Option<String>,
1079
1080 #[serde(rename = "type")]
1082 pub type_ref: TypeReference,
1083 #[serde(skip_serializing_if = "is_false", default)]
1102 pub required: bool,
1103 #[serde(skip_serializing_if = "is_false", default)]
1106 pub flattened: bool,
1107
1108 #[serde(skip, default)]
1109 pub transform_callback: String,
1110 #[serde(skip, default)]
1111 pub transform_callback_fn: Option<fn(&mut TypeReference, &Typespace) -> ()>,
1112}
1113
1114impl PartialEq for Field {
1115 fn eq(
1116 &self,
1117 Self {
1118 name,
1119 serde_name,
1120 description,
1121 deprecation_note,
1122 type_ref,
1123 required,
1124 flattened,
1125 transform_callback,
1126 transform_callback_fn: _,
1127 }: &Self,
1128 ) -> bool {
1129 self.name == *name
1130 && self.serde_name == *serde_name
1131 && self.description == *description
1132 && self.deprecation_note == *deprecation_note
1133 && self.type_ref == *type_ref
1134 && self.required == *required
1135 && self.flattened == *flattened
1136 && self.transform_callback == *transform_callback
1137 }
1138}
1139
1140impl std::hash::Hash for Field {
1141 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
1142 self.name.hash(state);
1143 self.serde_name.hash(state);
1144 self.description.hash(state);
1145 self.deprecation_note.hash(state);
1146 self.type_ref.hash(state);
1147 self.required.hash(state);
1148 self.flattened.hash(state);
1149 self.transform_callback.hash(state);
1150 }
1151}
1152
1153impl Field {
1154 pub fn new(name: String, type_ref: TypeReference) -> Self {
1155 Field {
1156 name,
1157 type_ref,
1158 serde_name: Default::default(),
1159 description: Default::default(),
1160 deprecation_note: Default::default(),
1161 required: Default::default(),
1162 flattened: Default::default(),
1163 transform_callback: Default::default(),
1164 transform_callback_fn: Default::default(),
1165 }
1166 }
1167
1168 pub fn with_required(mut self, required: bool) -> Self {
1169 self.required = required;
1170 self
1171 }
1172
1173 pub fn name(&self) -> &str {
1174 self.name.as_str()
1175 }
1176
1177 pub fn is_named(&self) -> bool {
1178 !self.is_unnamed()
1179 }
1180
1181 pub fn is_unnamed(&self) -> bool {
1182 self.name.parse::<u64>().is_ok()
1183 }
1184
1185 pub fn serde_name(&self) -> &str {
1186 if self.serde_name.is_empty() {
1187 self.name.as_str()
1188 } else {
1189 self.serde_name.as_str()
1190 }
1191 }
1192
1193 pub fn description(&self) -> &str {
1194 self.description.as_str()
1195 }
1196
1197 pub fn deprecated(&self) -> bool {
1198 self.deprecation_note.is_some()
1199 }
1200
1201 pub fn type_ref(&self) -> &TypeReference {
1202 &self.type_ref
1203 }
1204
1205 pub fn required(&self) -> bool {
1206 self.required
1207 }
1208
1209 pub fn flattened(&self) -> bool {
1210 self.flattened
1211 }
1212
1213 pub fn transform_callback(&self) -> &str {
1214 self.transform_callback.as_str()
1215 }
1216
1217 pub fn transform_callback_fn(&self) -> Option<fn(&mut TypeReference, &Typespace)> {
1218 self.transform_callback_fn
1219 }
1220}
1221
1222fn is_false(b: &bool) -> bool {
1223 !*b
1224}
1225
1226#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
1227pub struct Enum {
1228 pub name: String,
1229 #[serde(skip_serializing_if = "String::is_empty", default)]
1230 pub serde_name: String,
1231 #[serde(skip_serializing_if = "String::is_empty", default)]
1232 pub description: String,
1233
1234 #[serde(skip_serializing_if = "Vec::is_empty", default)]
1236 pub parameters: Vec<TypeParameter>,
1237
1238 #[serde(skip_serializing_if = "Representation::is_default", default)]
1239 pub representation: Representation,
1240
1241 #[serde(skip_serializing_if = "Vec::is_empty", default)]
1242 pub variants: Vec<Variant>,
1243
1244 #[serde(
1245 skip_serializing_if = "LanguageSpecificTypeCodegenConfig::is_serialization_default",
1246 default
1247 )]
1248 pub codegen_config: LanguageSpecificTypeCodegenConfig,
1249}
1250
1251impl Enum {
1252 pub fn new(name: String) -> Self {
1253 Enum {
1254 name,
1255 serde_name: Default::default(),
1256 description: Default::default(),
1257 parameters: Default::default(),
1258 representation: Default::default(),
1259 variants: Default::default(),
1260 codegen_config: Default::default(),
1261 }
1262 }
1263
1264 pub fn name(&self) -> &str {
1265 self.name.as_str()
1266 }
1267
1268 pub fn serde_name(&self) -> &str {
1269 if self.serde_name.is_empty() {
1270 self.name.as_str()
1271 } else {
1272 self.serde_name.as_str()
1273 }
1274 }
1275
1276 pub fn description(&self) -> &str {
1277 self.description.as_str()
1278 }
1279
1280 pub fn parameters(&self) -> std::slice::Iter<'_, TypeParameter> {
1281 self.parameters.iter()
1282 }
1283
1284 pub fn representation(&self) -> &Representation {
1285 &self.representation
1286 }
1287
1288 pub fn variants(&self) -> std::slice::Iter<'_, Variant> {
1289 self.variants.iter()
1290 }
1291}
1292
1293impl From<Enum> for Type {
1294 fn from(val: Enum) -> Self {
1295 Type::Enum(val)
1296 }
1297}
1298
1299#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
1300pub struct Variant {
1301 pub name: String,
1302 #[serde(skip_serializing_if = "String::is_empty", default)]
1303 pub serde_name: String,
1304 #[serde(skip_serializing_if = "String::is_empty", default)]
1305 pub description: String,
1306
1307 pub fields: Fields,
1308 #[serde(skip_serializing_if = "Option::is_none", default)]
1309 pub discriminant: Option<isize>,
1310
1311 #[serde(skip_serializing_if = "is_false", default)]
1313 pub untagged: bool,
1314}
1315
1316impl Variant {
1317 pub fn new(name: String) -> Self {
1318 Variant {
1319 name,
1320 serde_name: String::new(),
1321 description: String::new(),
1322 fields: Fields::None,
1323 discriminant: None,
1324 untagged: false,
1325 }
1326 }
1327
1328 pub fn name(&self) -> &str {
1329 self.name.as_str()
1330 }
1331
1332 pub fn serde_name(&self) -> &str {
1333 if self.serde_name.is_empty() {
1334 self.name.as_str()
1335 } else {
1336 self.serde_name.as_str()
1337 }
1338 }
1339
1340 pub fn description(&self) -> &str {
1341 self.description.as_str()
1342 }
1343
1344 pub fn fields(&self) -> std::slice::Iter<'_, Field> {
1345 self.fields.iter()
1346 }
1347
1348 pub fn discriminant(&self) -> Option<isize> {
1349 self.discriminant
1350 }
1351
1352 pub fn untagged(&self) -> bool {
1353 self.untagged
1354 }
1355}
1356
1357#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Eq, PartialEq, Hash, Default)]
1358#[serde(rename_all = "snake_case")]
1359pub enum Representation {
1360 #[default]
1366 External,
1367
1368 Internal { tag: String },
1374
1375 Adjacent { tag: String, content: String },
1381
1382 None,
1388}
1389
1390impl Representation {
1391 pub fn new() -> Self {
1392 Default::default()
1393 }
1394
1395 pub fn is_default(&self) -> bool {
1396 matches!(self, Representation::External)
1397 }
1398
1399 pub fn is_external(&self) -> bool {
1400 matches!(self, Representation::External)
1401 }
1402
1403 pub fn is_internal(&self) -> bool {
1404 matches!(self, Representation::Internal { .. })
1405 }
1406
1407 pub fn is_adjacent(&self) -> bool {
1408 matches!(self, Representation::Adjacent { .. })
1409 }
1410
1411 pub fn is_none(&self) -> bool {
1412 matches!(self, Representation::None)
1413 }
1414}
1415
1416#[cfg(test)]
1417mod tests {
1418 use super::*;
1419
1420 fn primitive(name: &str) -> Type {
1421 Type::Primitive(Primitive {
1422 name: name.to_string(),
1423 description: String::new(),
1424 parameters: vec![],
1425 fallback: None,
1426 codegen_config: LanguageSpecificTypeCodegenConfig::default(),
1427 })
1428 }
1429
1430 #[test]
1437 fn remove_type_keeps_map_consistent_across_multiple_removals() {
1438 let mut ts = Typespace::default();
1439 ts.insert_type(primitive("a"));
1440 ts.insert_type(primitive("b"));
1441 ts.insert_type(primitive("c"));
1442 ts.insert_type(primitive("d"));
1443
1444 let _ = ts.remove_type("b");
1446 let _ = ts.remove_type("c");
1447
1448 assert!(ts.has_type("a"), "untouched type 'a' should still resolve");
1449 assert!(ts.has_type("d"), "untouched type 'd' should still resolve");
1450 assert!(!ts.has_type("b"));
1451 assert!(!ts.has_type("c"));
1452
1453 assert_eq!(ts.get_type("a").map(|t| t.name()), Some("a"));
1456 assert_eq!(ts.get_type("d").map(|t| t.name()), Some("d"));
1457 }
1458
1459 #[test]
1460 fn remove_type_returns_the_value_we_asked_for() {
1461 let mut ts = Typespace::default();
1462 ts.insert_type(primitive("first"));
1463 ts.insert_type(primitive("second"));
1464 ts.insert_type(primitive("third"));
1465
1466 let removed = ts.remove_type("second").expect("should find 'second'");
1467 assert_eq!(removed.name(), "second");
1468
1469 assert_eq!(ts.get_type("first").map(|t| t.name()), Some("first"));
1471 assert_eq!(ts.get_type("third").map(|t| t.name()), Some("third"));
1472 }
1473}