1mod defs;
2mod fabric;
3mod generic;
4mod origin;
5mod types;
6
7pub use defs::Composite;
8pub use defs::Primitive;
9pub use defs::Referred;
10pub use fabric::{TypeAsString, TypeTokenStream, VariableTokenStream};
11pub use generic::ExtractGenerics;
12pub use origin::OriginType;
13pub use types::Extract;
14
15use crate::{context::Context, error::E};
16use std::{collections::HashMap, ops::Deref};
17
18pub struct NatureDef {
19 pub nature: Nature,
20 pub module: Option<String>,
21}
22
23impl NatureDef {
24 pub fn new(nature: Nature, module: Option<String>) -> Self {
25 Self { nature, module }
26 }
27 pub fn get_mut(&mut self) -> &mut Nature {
28 &mut self.nature
29 }
30 pub fn get(&self) -> &Nature {
31 &self.nature
32 }
33 pub fn extract(&self) -> Nature {
34 self.nature.clone()
35 }
36}
37pub struct Natures(HashMap<String, NatureDef>);
38
39impl Natures {
40 pub fn new() -> Self {
41 Natures(HashMap::new())
42 }
43 pub fn is_any_bound(natures: &[Nature]) -> bool {
44 for nature in natures.iter() {
45 if let Nature::Referred(Referred::Field(_, _, _, binding)) = nature {
46 if binding.is_some() {
47 return true;
48 }
49 }
50 }
51 false
52 }
53 pub fn get_fn_args_names(args: &[Nature]) -> Vec<String> {
54 args.iter()
55 .filter_map(|arg| {
56 if let Nature::Referred(Referred::FuncArg(name, _, _, _)) = arg {
57 Some(name.to_owned())
58 } else {
59 None
60 }
61 })
62 .collect::<Vec<String>>()
63 }
64 pub fn contains(&self, name: &str) -> bool {
65 self.0.contains_key(name)
66 }
67 pub fn insert(&mut self, name: &str, nature: Nature, module: Option<String>) -> Result<(), E> {
68 if self.contains(name) {
69 Err(E::EntityExist(name.to_owned()))
70 } else {
71 let _ = self
72 .0
73 .insert(name.to_owned(), NatureDef::new(nature, module));
74 Ok(())
75 }
76 }
77 pub fn get_module_of(&self, name: &str) -> Option<String> {
78 self.0.get(name).and_then(|n| n.module.clone())
79 }
80 pub fn exists_in_module(&self, name: &str, module: &str) -> bool {
81 self.0
82 .get(name)
83 .map(|n| n.module.as_ref().map(|m| m == module).unwrap_or_default())
84 .unwrap_or_default()
85 }
86 pub fn get_mut(
87 &mut self,
88 name: &str,
89 default_nature: Option<Nature>,
90 default_module: Option<String>,
91 ) -> Option<&mut Nature> {
92 if let (exists, Some(default_nature)) = (self.0.contains_key(name), default_nature) {
93 if !exists {
94 let _ = self.0.insert(
95 name.to_owned(),
96 NatureDef::new(default_nature, default_module),
97 );
98 }
99 }
100 self.0.get_mut(name).map(|n| n.get_mut())
101 }
102
103 pub fn filter(&self, filter: fn(&Nature) -> bool) -> Vec<Nature> {
104 let mut natures: Vec<Nature> = vec![];
105 for (_, n) in self.0.iter() {
106 if filter(n.get()) {
107 natures.push(n.extract());
108 }
109 }
110 natures
111 }
112
113 pub fn iter(&self) -> impl Iterator<Item = (&String, &Nature)> {
114 self.0.iter().map(|(k, n)| (k, n.get()))
115 }
116}
117
118#[derive(Clone, Debug)]
119pub enum Nature {
120 Primitive(Primitive),
121 Referred(Referred),
122 Composite(Composite),
123}
124
125impl Nature {
126 pub fn get_fn_args_names(&self) -> Result<Vec<String>, E> {
127 if let Nature::Composite(Composite::Func(_, args, _, _, _)) = self {
128 Ok(Natures::get_fn_args_names(args))
129 } else {
130 Err(E::Parsing("Fail to find arguments of function".to_string()))
131 }
132 }
133
134 pub fn is_fn_async(&self) -> Result<bool, E> {
135 if let Nature::Composite(Composite::Func(_, _, _, asyncness, _)) = self {
136 Ok(*asyncness)
137 } else {
138 Err(E::Parsing("Fail to find function".to_string()))
139 }
140 }
141
142 pub fn bind(&mut self, nature: Nature) -> Result<(), E> {
143 match self {
144 Self::Primitive(_) => Err(E::Parsing(String::from("Primitive type cannot be bound"))),
145 Self::Referred(re) => match re {
146 Referred::Struct(_, _, natures) => {
147 natures.push(nature);
148 Ok(())
149 }
150 Referred::TupleStruct(_, _, field) => {
151 let _ = field.insert(Box::new(nature));
152 Ok(())
153 }
154 Referred::Enum(_, _, natures, ..) => {
155 natures.push(nature);
156 Ok(())
157 }
158 Referred::EnumVariant(_, _, natures, ..) => {
159 natures.push(nature);
160 Ok(())
161 }
162 _ => Err(E::NotSupported("Referred".to_owned())),
163 },
164 Self::Composite(othr) => match othr {
165 Composite::HashMap(_, k, v) => {
166 if k.is_none() {
167 if let Self::Primitive(p) = nature {
168 let _ = k.insert(p);
169 Ok(())
170 } else {
171 Err(E::Parsing(String::from(
172 "HashMap can use as key only Primitive type",
173 )))
174 }
175 } else if v.is_none() {
176 let _ = v.insert(Box::new(nature));
177 Ok(())
178 } else {
179 Err(E::Parsing(String::from(
180 "HashMap entity already has been bound",
181 )))
182 }
183 }
184 Composite::Option(_, o) => {
185 if o.is_some() {
186 Err(E::Parsing(String::from(
187 "Option entity already has been bound",
188 )))
189 } else {
190 let _ = o.insert(Box::new(nature));
191 Ok(())
192 }
193 }
194 Composite::Result(_, r, e, _, _) => {
195 if r.is_some() && e.is_some() {
196 Err(E::Parsing(String::from(
197 "Result entity already has been bound",
198 )))
199 } else if r.is_none() {
200 let _ = r.insert(Box::new(nature));
201
202 Ok(())
203 } else {
204 let _ = e.insert(Box::new(nature));
205 Ok(())
206 }
207 }
208 Composite::Tuple(_, tys) => {
209 tys.push(nature);
210 Ok(())
211 }
212 Composite::Vec(_, v) => {
213 if v.is_some() {
214 Err(E::Parsing(String::from(
215 "Vec entity already has been bound",
216 )))
217 } else {
218 let _ = v.insert(Box::new(nature));
219 Ok(())
220 }
221 }
222 _ => Err(E::NotSupported(String::from("Composite"))),
223 },
224 }
225 }
226
227 pub fn is_method_constructor(&self) -> bool {
228 if let Nature::Referred(Referred::Field(_, _, nature, _)) = self {
229 if let Nature::Composite(Composite::Func(_, _, _, _, constructor)) = nature.deref() {
230 return *constructor;
231 }
232 }
233 false
234 }
235
236 pub fn is_field_ignored(&self) -> bool {
237 if let Nature::Referred(Referred::Field(name, context, _, _)) = self {
238 context.is_ignored(name)
239 } else {
240 false
241 }
242 }
243
244 pub fn check_ignored_fields(&self) -> Result<(), E> {
245 if let Nature::Referred(Referred::Struct(name, context, fields)) = self {
246 let ignored = context.ignored_list();
247 if ignored.is_empty() {
248 return Ok(());
249 }
250 let existed = fields
251 .iter()
252 .filter_map(|f| {
253 if let Nature::Referred(Referred::Field(name, _, _, _)) = f {
254 Some(name.to_owned())
255 } else {
256 None
257 }
258 })
259 .collect::<Vec<String>>();
260 for n in ignored {
261 if !existed.iter().any(|name| name == &n) {
262 return Err(E::Parsing(format!(
263 "Field in ignored list \"{n}\" isn't found in struct \"{name}\""
264 )));
265 }
266 }
267 Ok(())
268 } else {
269 Ok(())
270 }
271 }
272
273 pub fn get_context(&self) -> Result<&Context, E> {
274 Ok(match self {
275 Self::Primitive(_) => Err(E::Parsing(String::from("Primitives do not have context")))?,
276 Self::Composite(_composite) => {
277 Err(E::Parsing(String::from("Composite do not have context")))?
278 }
279 Self::Referred(refered) => match refered {
280 Referred::Enum(_, context, ..) => context,
281 Referred::EnumVariant(_, context, ..) => context,
282 Referred::Field(_, context, ..) => context,
283 Referred::Func(_, context, ..) => context,
284 Referred::FuncArg(_, context, ..) => context,
285 Referred::TupleStruct(_, context, ..) => context,
286 Referred::Struct(_, context, ..) => context,
287 Referred::Constant(_, context, ..) => context,
288 Referred::Ref(..) => {
289 Err(E::Parsing(String::from("Reference do not have context")))?
290 }
291 Referred::Generic(..) => {
292 Err(E::Parsing(String::from("Generic do not have context")))?
293 }
294 },
295 })
296 }
297}