1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
use std::error::Error;
use quote::quote;
use syn::{parse_quote, Stmt};
use crate::{ConstructableStructure, EnumStructure, Structure, TypeOfSelf};
pub struct Item<'a> {
pub structure: &'a mut Structure,
pub self_type: TypeOfSelf,
}
impl Item<'_> {
pub fn map_constructable(
&mut self,
cb: impl for<'a> Fn(ConstructableStructure<'a>) -> Result<Vec<Stmt>, Box<dyn Error>>,
) -> Result<Vec<Stmt>, Box<dyn Error>> {
let type_of_self = self.self_type;
match self.structure {
Structure::Enum(EnumStructure {
attrs: ref enum_attrs,
variants,
..
}) => {
let branches = variants
.iter_mut()
.map(|variant| {
let result = cb(ConstructableStructure::EnumVariant(variant, enum_attrs));
match result {
Ok(lines) => {
let pattern = variant
.fields
.to_pattern(variant.full_path.clone(), type_of_self);
Ok(quote!( #pattern => {
#(#lines)*
}))
}
Err(err) => Err(err),
}
})
.collect::<Result<Vec<_>, _>>()?;
Ok(vec![parse_quote!(match self {
#(#branches)*
})])
}
Structure::Struct(r#struct) => {
let result = cb(ConstructableStructure::Struct(r#struct));
match result {
Ok(mut lines) => {
let pattern = r#struct
.fields
.to_pattern(r#struct.name.clone().into(), self.self_type);
let destructuring_stmt = parse_quote! {
let #pattern = self;
};
lines.insert(0, destructuring_stmt);
Ok(lines)
}
Err(err) => Err(err),
}
}
}
}
pub fn evaluate_pattern() {}
}