1use proc_macro2::TokenStream;
2
3use crate::{Result, Field, Fields, Variant, Struct, Enum, Input};
4
5type FnOutput = TokenStream;
7
8pub trait Mapper {
9 trait_method!(map_input: Input<'_>, input_default);
10 trait_method!(map_struct: Struct<'_>, struct_default);
11 trait_method!(map_enum: Enum<'_>, enum_default);
12 trait_method!(map_variant: Variant<'_>, variant_default);
13 trait_method!(map_fields: Fields<'_>, fields_default);
14 trait_method!(map_field: Field<'_>, field_default);
15}
16
17impl<M: Mapper + ?Sized> Mapper for &mut M {
18 trait_forward!(<M as Mapper>::map_input: Input<'_>);
19 trait_forward!(<M as Mapper>::map_struct: Struct<'_>);
20 trait_forward!(<M as Mapper>::map_enum: Enum<'_>);
21 trait_forward!(<M as Mapper>::map_variant: Variant<'_>);
22 trait_forward!(<M as Mapper>::map_fields: Fields<'_>);
23 trait_forward!(<M as Mapper>::map_field: Field<'_>);
24}
25
26impl Mapper for TokenStream {
27 fn map_input(&mut self, _: Input<'_>) -> Result<FnOutput> {
28 Ok(self.clone())
29 }
30}
31
32#[derive(Default)]
33pub struct MapperBuild {
34 output_mapper: function!(TokenStream),
35 input_mapper: function!(Input<'_>),
36 struct_mapper: function!(Struct<'_>),
37 enum_mapper: function!(Enum<'_>),
38 variant_mapper: function!(Variant<'_>),
39 fields_mapper: function!(Fields<'_>),
40 field_mapper: function!(Field<'_>),
41}
42
43impl MapperBuild {
44 pub fn new() -> Self {
45 MapperBuild::default()
46 }
47
48 builder!(with_output: TokenStream, output_mapper);
49 try_builder!(try_with_output: TokenStream, output_mapper);
50
51 builder!(input_map: Input<'_>, input_mapper);
52 try_builder!(try_input_map: Input<'_>, input_mapper);
53
54 builder!(struct_map: Struct<'_>, struct_mapper);
55 try_builder!(try_struct_map: Struct<'_>, struct_mapper);
56
57 builder!(enum_map: Enum<'_>, enum_mapper);
58 try_builder!(try_enum_map: Enum<'_>, enum_mapper);
59
60 builder!(variant_map: Variant<'_>, variant_mapper);
61 try_builder!(try_variant_map: Variant<'_>, variant_mapper);
62
63 builder!(fields_map: Fields<'_>, fields_mapper);
64 try_builder!(try_fields_map: Fields<'_>, fields_mapper);
65
66 builder!(field_map: Field<'_>, field_mapper);
67 try_builder!(try_field_map: Field<'_>, field_mapper);
68}
69
70impl Mapper for MapperBuild {
71 fn map_input(&mut self, value: Input<'_>) -> Result<TokenStream> {
72 let output = match self.input_mapper.take() {
73 Some(mut m) => {
74 let result = m(self, value);
75 self.input_mapper = Some(m);
76 result?
77 }
78 None => input_default(&mut *self, value)?
79 };
80
81 match self.output_mapper.take() {
82 Some(mut m) => {
83 let result = m(self, output);
84 self.output_mapper = Some(m);
85 result
86 }
87 _ => Ok(output)
88 }
89 }
90
91 builder_forward!(map_struct: Struct<'_>, struct_mapper, struct_default);
92 builder_forward!(map_enum: Enum<'_>, enum_mapper, enum_default);
93 builder_forward!(map_variant: Variant<'_>, variant_mapper, variant_default);
94 builder_forward!(map_fields: Fields<'_>, fields_mapper, fields_default);
95 builder_forward!(map_field: Field<'_>, field_mapper, field_default);
96}
97
98pub fn input_default<M: Mapper>(mut mapper: M, value: Input<'_>) -> Result<TokenStream> {
99 match value {
100 Input::Struct(v) => mapper.map_struct(v),
101 Input::Enum(v) => mapper.map_enum(v),
102 Input::Union(_) => unimplemented!("union mapping is unimplemented")
103 }
104}
105
106pub fn enum_default<M: Mapper>(mut mapper: M, value: Enum<'_>) -> Result<TokenStream> {
107 let variant = value.variants().map(|v| &v.inner.ident);
108 let fields = value.variants().map(|v| v.fields().match_tokens());
109 let enum_name = ::std::iter::repeat(value.parent.ident());
110 let expression = value.variants()
111 .map(|v| mapper.map_variant(v))
112 .collect::<Result<Vec<_>>>()?;
113
114 Ok(quote! {
115 match self {
120 #(#enum_name::#variant #fields => { #expression }),*
121 }
122 })
123}
124
125pub fn struct_default<M: Mapper>(mut mapper: M, value: Struct) -> Result<TokenStream> {
126 mapper.map_fields(value.fields())
127}
128
129pub fn variant_default<M: Mapper>(mut mapper: M, value: Variant) -> Result<TokenStream> {
130 mapper.map_fields(value.fields())
131}
132
133pub fn fields_null<M: Mapper>(mut mapper: M, value: Fields) -> Result<TokenStream> {
134 let field = value.iter()
135 .map(|field| mapper.map_field(field))
136 .collect::<Result<Vec<_>>>()?;
137
138 Ok(quote!(#(#field)*))
139}
140
141pub fn fields_default<M: Mapper>(mut mapper: M, value: Fields) -> Result<TokenStream> {
142 let field = value.iter()
143 .map(|field| mapper.map_field(field))
144 .collect::<Result<Vec<_>>>()?;
145
146 Ok(quote!({ #(#field)* }))
147}
148
149pub fn field_default<M: Mapper>(_: M, _: Field) -> Result<TokenStream> {
150 Ok(TokenStream::new())
151}
152
153pub fn enum_null<M: Mapper>(mut mapper: M, value: Enum<'_>) -> Result<TokenStream> {
154 let expression = value.variants()
155 .map(|v| mapper.map_variant(v))
156 .collect::<Result<Vec<_>>>()?;
157
158 Ok(quote!(#(#expression)*))
159}