1pub use std::collections::HashMap;
2
3pub use super::{
4 types::{Alias, Enum, NewType, Struct, TypeRef, Union},
5 TypeId,
6};
7
8#[derive(Default)]
13pub struct TypeRegistry {
14 pub(super) types: HashMap<TypeId, Type>,
16
17 pub(super) structs: Vec<TypeId>,
19 pub(super) enums: Vec<TypeId>,
21 pub(super) unions: Vec<TypeId>,
23 pub(super) newtypes: Vec<TypeId>,
25 pub(super) aliases: Vec<TypeId>,
27}
28
29impl TypeRegistry {
30 pub fn new() -> Self {
32 TypeRegistry::default()
33 }
34
35 pub fn register_alias(&mut self, id: TypeId, details: Alias) -> TypeRef {
39 if !self.types.contains_key(&id) {
40 self.aliases.push(id.clone());
41 }
42 self.register_type(id, Type::Alias(details))
43 }
44
45 pub fn register_struct(&mut self, id: TypeId, details: Struct) -> TypeRef {
49 if !self.types.contains_key(&id) {
50 self.structs.push(id.clone());
51 }
52 self.register_type(id, Type::Struct(details))
53 }
54
55 pub fn register_newtype(&mut self, id: TypeId, details: NewType) -> TypeRef {
59 if !self.types.contains_key(&id) {
60 self.newtypes.push(id.clone());
61 }
62 self.register_type(id, Type::NewType(details))
63 }
64
65 pub fn register_enum(&mut self, id: TypeId, details: Enum) -> TypeRef {
69 if !self.types.contains_key(&id) {
70 self.enums.push(id.clone());
71 }
72 self.register_type(id, Type::Enum(details))
73 }
74
75 pub fn register_union(&mut self, id: TypeId, details: Union) -> TypeRef {
79 if !self.types.contains_key(&id) {
80 self.unions.push(id.clone());
81 }
82 self.register_type(id, Type::Union(details))
83 }
84
85 fn register_type(&mut self, id: TypeId, ty: Type) -> TypeRef {
86 if self.types.contains_key(&id) {
87 match self.types.get(&id) {
88 Some(existing) if ty.same_kind(existing) => return existing.type_ref(),
89 other => panic!("Type register mismatch: {:?} vs {:?}", ty, other),
90 }
91 }
92
93 let type_ref = ty.type_ref();
94 self.types.insert(id, ty);
95
96 type_ref
97 }
98}
99
100#[derive(Debug)]
101#[allow(clippy::enum_variant_names)]
102pub enum Type {
103 Struct(Struct),
104 Enum(Enum),
105 Union(Union),
106 NewType(NewType),
107 Alias(Alias),
108}
109
110impl Type {
111 fn type_ref(&self) -> TypeRef {
112 match self {
113 Type::Struct(st) => TypeRef {
114 name: st.name.clone(),
115 },
116 Type::Enum(en) => TypeRef {
117 name: en.name.clone(),
118 },
119 Type::Union(un) => TypeRef {
120 name: un.name.clone(),
121 },
122 Type::NewType(nt) => TypeRef {
123 name: nt.name.clone(),
124 },
125 Type::Alias(nt) => TypeRef {
126 name: nt.name.clone(),
127 },
128 }
129 }
130
131 #[allow(clippy::match_like_matches_macro)]
132 fn same_kind(&self, other: &Type) -> bool {
133 match (self, other) {
134 (Type::Struct(_), Type::Struct(_)) => true,
135 (Type::Enum(_), Type::Enum(_)) => true,
136 (Type::Union(_), Type::Union(_)) => true,
137 (Type::NewType(_), Type::NewType(_)) => true,
138 _ => false,
139 }
140 }
141}