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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
use super::*;
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct DeriveInput {
pub ident: Ident,
pub vis: Visibility,
pub attrs: Vec<Attribute>,
pub generics: Generics,
pub body: Body,
}
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub enum Body {
Enum(Vec<Variant>),
Struct(VariantData),
}
#[cfg(feature = "parsing")]
pub mod parsing {
use super::*;
use Generics;
use attr::parsing::outer_attr;
use data::parsing::{visibility, struct_body, enum_body};
use generics::parsing::generics;
use ident::parsing::ident;
named!(pub derive_input -> DeriveInput, do_parse!(
attrs: many0!(outer_attr) >>
vis: visibility >>
which: alt!(keyword!("struct") | keyword!("enum")) >>
id: ident >>
generics: generics >>
item: switch!(value!(which),
"struct" => map!(struct_body, move |(wh, body)| DeriveInput {
ident: id,
vis: vis,
attrs: attrs,
generics: Generics {
where_clause: wh,
.. generics
},
body: Body::Struct(body),
})
|
"enum" => map!(enum_body, move |(wh, body)| DeriveInput {
ident: id,
vis: vis,
attrs: attrs,
generics: Generics {
where_clause: wh,
.. generics
},
body: Body::Enum(body),
})
) >>
(item)
));
}
#[cfg(feature = "printing")]
mod printing {
use super::*;
use attr::FilterAttrs;
use data::VariantData;
use quote::{Tokens, ToTokens};
impl ToTokens for DeriveInput {
fn to_tokens(&self, tokens: &mut Tokens) {
for attr in self.attrs.outer() {
attr.to_tokens(tokens);
}
self.vis.to_tokens(tokens);
match self.body {
Body::Enum(_) => tokens.append("enum"),
Body::Struct(_) => tokens.append("struct"),
}
self.ident.to_tokens(tokens);
self.generics.to_tokens(tokens);
match self.body {
Body::Enum(ref variants) => {
self.generics.where_clause.to_tokens(tokens);
tokens.append("{");
for variant in variants {
variant.to_tokens(tokens);
tokens.append(",");
}
tokens.append("}");
}
Body::Struct(ref variant_data) => {
match *variant_data {
VariantData::Struct(_) => {
self.generics.where_clause.to_tokens(tokens);
variant_data.to_tokens(tokens);
}
VariantData::Tuple(_) => {
variant_data.to_tokens(tokens);
self.generics.where_clause.to_tokens(tokens);
tokens.append(";");
}
VariantData::Unit => {
self.generics.where_clause.to_tokens(tokens);
tokens.append(";");
}
}
}
}
}
}
}