1mod array;
6mod basic;
7mod composite;
8mod constants;
9mod function;
10mod genericity;
11mod non_zero;
12mod option;
13mod result;
14mod tuple;
15
16use std::collections::HashMap;
17
18pub use array::Array;
19pub use basic::CoreBasic;
20pub use composite::{Composite, CompositeInner, CompositeInnerKind, CompositeType};
21pub use function::{Function, FunctionOutputKind, StateMutability};
22pub use non_zero::NonZero;
23pub use option::Option;
24pub use result::Result;
25pub use tuple::Tuple;
26
27use crate::{CainomeResult, Error};
28
29#[derive(Debug, Clone, PartialEq)]
30pub enum Token {
31 CoreBasic(CoreBasic),
32 Array(Array),
33 Tuple(Tuple),
34 Composite(Composite),
35 Function(Function),
36 Option(Option),
37 Result(Result),
38 NonZero(NonZero),
39}
40
41impl Token {
42 pub fn parse(type_path: &str) -> CainomeResult<Self> {
43 if let Ok(b) = CoreBasic::parse(type_path) {
44 return Ok(Token::CoreBasic(b));
45 }
46
47 if let Ok(a) = Array::parse(type_path) {
48 return Ok(Token::Array(a));
49 }
50
51 if let Ok(t) = Tuple::parse(type_path) {
52 return Ok(Token::Tuple(t));
53 }
54
55 if let Ok(o) = Option::parse(type_path) {
56 return Ok(Token::Option(o));
57 }
58
59 if let Ok(r) = Result::parse(type_path) {
60 return Ok(Token::Result(r));
61 }
62
63 if let Ok(n) = NonZero::parse(type_path) {
64 return Ok(Token::NonZero(n));
65 }
66
67 if let Ok(c) = Composite::parse(type_path) {
68 return Ok(Token::Composite(c));
69 }
70
71 Err(Error::TokenInitFailed(format!(
72 "Couldn't initialize a Token from type path `{}`",
73 type_path,
74 )))
75 }
76
77 pub fn type_name(&self) -> String {
78 match self {
79 Token::CoreBasic(t) => t.type_name(),
80 Token::Array(_) => "array".to_string(),
81 Token::Tuple(_) => "tuple".to_string(),
82 Token::Composite(t) => t.type_name(),
83 Token::Function(_) => "function".to_string(),
84 Token::Option(_) => "option".to_string(),
85 Token::Result(_) => "result".to_string(),
86 Token::NonZero(_) => "non_zero".to_string(),
87 }
88 }
89
90 pub fn type_path(&self) -> String {
91 match self {
92 Token::CoreBasic(t) => t.type_path.to_string(),
93 Token::Array(t) => t.type_path.to_string(),
94 Token::Tuple(t) => t.type_path.to_string(),
95 Token::Composite(t) => t.type_path_no_generic(),
96 Token::Function(t) => t.name.clone(),
97 Token::Option(t) => t.type_path.to_string(),
98 Token::Result(t) => t.type_path.to_string(),
99 Token::NonZero(t) => t.type_path.to_string(),
100 }
101 }
102
103 pub fn to_composite(&self) -> CainomeResult<&Composite> {
105 match self {
106 Token::Composite(t) => Ok(t),
107 _ => Err(Error::ConversionFailed(format!(
108 "Can't convert token into composite, got {:?}",
109 self
110 ))),
111 }
112 }
113
114 pub fn to_function(&self) -> CainomeResult<&Function> {
115 match self {
116 Token::Function(t) => Ok(t),
117 _ => Err(Error::ConversionFailed(format!(
118 "Can't convert token into function, got {:?}",
119 self
120 ))),
121 }
122 }
123
124 pub fn apply_alias(&mut self, type_path: &str, alias: &str) {
125 match self {
126 Token::Array(t) => t.apply_alias(type_path, alias),
127 Token::Tuple(t) => t.apply_alias(type_path, alias),
128 Token::Composite(t) => t.apply_alias(type_path, alias),
129 Token::Function(t) => t.apply_alias(type_path, alias),
130 Token::Option(t) => t.apply_alias(type_path, alias),
131 Token::Result(t) => t.apply_alias(type_path, alias),
132 _ => (),
133 }
134 }
135
136 pub fn hydrate(
152 token: Self,
153 filtered: &HashMap<String, Token>,
154 recursion_max_depth: usize,
155 iteration_count: usize,
156 ) -> Self {
157 if recursion_max_depth < iteration_count {
158 return token;
159 }
160 match token {
161 Token::CoreBasic(_) => token,
162 Token::Array(arr) => Token::Array(Array {
163 inner: Box::new(Self::hydrate(
164 *arr.inner,
165 filtered,
166 recursion_max_depth,
167 iteration_count + 1,
168 )),
169 type_path: arr.type_path,
170 is_legacy: arr.is_legacy,
171 }),
172 Token::Tuple(tup) => Token::Tuple(Tuple {
173 inners: tup
174 .inners
175 .into_iter()
176 .map(|inner| {
177 Self::hydrate(inner, filtered, recursion_max_depth, iteration_count + 1)
178 })
179 .collect(),
180 type_path: tup.type_path,
181 }),
182 Token::Option(opt) => Token::Option(Option {
183 type_path: opt.type_path,
184 inner: Box::new(Self::hydrate(
185 *opt.inner,
186 filtered,
187 recursion_max_depth,
188 iteration_count + 1,
189 )),
190 }),
191 Token::NonZero(non_zero) => Token::NonZero(NonZero {
192 type_path: non_zero.type_path,
193 inner: Box::new(Self::hydrate(
194 *non_zero.inner,
195 filtered,
196 recursion_max_depth,
197 iteration_count + 1,
198 )),
199 }),
200 Token::Result(res) => Token::Result(Result {
201 type_path: res.type_path,
202 inner: Box::new(Self::hydrate(
203 *res.inner,
204 filtered,
205 recursion_max_depth,
206 iteration_count + 1,
207 )),
208 error: Box::new(Self::hydrate(
209 *res.error,
210 filtered,
211 recursion_max_depth,
212 iteration_count + 1,
213 )),
214 }),
215 Token::Composite(comp) => {
216 let type_path = comp.type_path_no_generic();
217
218 if comp.r#type == CompositeType::Unknown && !comp.is_builtin() {
219 if let Some(hydrated) = filtered.get(&type_path) {
220 return Token::hydrate(
221 hydrated.clone(),
222 filtered,
223 recursion_max_depth,
224 iteration_count + 1,
225 );
226 } else {
227 panic!("Composite {} not found in filtered tokens", type_path);
228 }
229 }
230 Token::Composite(Composite {
231 type_path,
232 inners: comp
233 .inners
234 .into_iter()
235 .map(|i| CompositeInner {
236 index: i.index,
237 name: i.name,
238 kind: i.kind,
239 token: Self::hydrate(
240 i.token,
241 filtered,
242 recursion_max_depth,
243 iteration_count + 1,
244 ),
245 })
246 .collect(),
247 generic_args: comp
248 .generic_args
249 .into_iter()
250 .map(|(name, token)| {
251 (
252 name,
253 Self::hydrate(
254 token,
255 filtered,
256 recursion_max_depth,
257 iteration_count + 1,
258 ),
259 )
260 })
261 .collect(),
262 r#type: comp.r#type,
263 is_event: comp.is_event,
264 alias: comp.alias,
265 })
266 }
267 Token::Function(func) => Token::Function(Function {
268 name: func.name,
269 inputs: func
270 .inputs
271 .into_iter()
272 .map(|(name, token)| {
273 (
274 name,
275 Self::hydrate(
276 token,
277 filtered,
278 recursion_max_depth,
279 iteration_count + 1,
280 ),
281 )
282 })
283 .collect(),
284 outputs: func
285 .outputs
286 .into_iter()
287 .map(|token| {
288 Self::hydrate(token, filtered, recursion_max_depth, iteration_count + 1)
289 })
290 .collect(),
291 named_outputs: func
292 .named_outputs
293 .into_iter()
294 .map(|(name, token)| {
295 (
296 name,
297 Self::hydrate(
298 token,
299 filtered,
300 recursion_max_depth,
301 iteration_count + 1,
302 ),
303 )
304 })
305 .collect(),
306 state_mutability: func.state_mutability,
307 }),
308 }
309 }
310}