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