blob: 71d675435e46acc918d649a85f191f8c3afa6606 [file] [log] [blame]
David Tolnayf38cdf62016-09-23 19:07:09 -07001use super::*;
2
3#[derive(Debug, Clone, Eq, PartialEq)]
4pub struct Variant {
5 pub ident: Ident,
6 pub attrs: Vec<Attribute>,
7 pub data: VariantData,
8 /// Explicit discriminant, e.g. `Foo = 1`
David Tolnay3cb23a92016-10-07 23:02:21 -07009 pub discriminant: Option<ConstExpr>,
David Tolnayf38cdf62016-09-23 19:07:09 -070010}
11
12#[derive(Debug, Clone, Eq, PartialEq)]
13pub enum VariantData {
14 Struct(Vec<Field>),
15 Tuple(Vec<Field>),
16 Unit,
17}
18
19impl VariantData {
20 pub fn fields(&self) -> &[Field] {
21 match *self {
22 VariantData::Struct(ref fields) |
23 VariantData::Tuple(ref fields) => fields,
24 VariantData::Unit => &[],
25 }
26 }
Sean Griffin15085c42016-10-03 11:40:31 -040027
28 pub fn fields_mut(&mut self) -> &mut [Field] {
29 match *self {
30 VariantData::Struct(ref mut fields) |
31 VariantData::Tuple(ref mut fields) => fields,
32 VariantData::Unit => &mut [],
33 }
34 }
David Tolnayf38cdf62016-09-23 19:07:09 -070035}
36
37#[derive(Debug, Clone, Eq, PartialEq)]
38pub struct Field {
39 pub ident: Option<Ident>,
40 pub vis: Visibility,
41 pub attrs: Vec<Attribute>,
42 pub ty: Ty,
43}
44
45#[derive(Debug, Copy, Clone, Eq, PartialEq)]
46pub enum Visibility {
47 Public,
48 Inherited,
49}
50
David Tolnayf38cdf62016-09-23 19:07:09 -070051#[cfg(feature = "parsing")]
52pub mod parsing {
53 use super::*;
David Tolnay4a51dc72016-10-01 00:40:31 -070054 use attr::parsing::outer_attr;
David Tolnay3cb23a92016-10-07 23:02:21 -070055 use constant::parsing::const_expr;
David Tolnayf38cdf62016-09-23 19:07:09 -070056 use ident::parsing::ident;
David Tolnayf38cdf62016-09-23 19:07:09 -070057 use ty::parsing::ty;
David Tolnayf38cdf62016-09-23 19:07:09 -070058
59 named!(pub struct_body -> VariantData, alt!(
60 struct_like_body => { VariantData::Struct }
61 |
62 terminated!(tuple_like_body, punct!(";")) => { VariantData::Tuple }
63 |
64 punct!(";") => { |_| VariantData::Unit }
65 ));
66
67 named!(pub enum_body -> Vec<Variant>, do_parse!(
68 punct!("{") >>
69 variants: separated_list!(punct!(","), variant) >>
70 option!(punct!(",")) >>
71 punct!("}") >>
72 (variants)
73 ));
74
75 named!(variant -> Variant, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -070076 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -070077 id: ident >>
78 data: alt!(
79 struct_like_body => { VariantData::Struct }
80 |
81 tuple_like_body => { VariantData::Tuple }
82 |
83 epsilon!() => { |_| VariantData::Unit }
84 ) >>
David Tolnay3cb23a92016-10-07 23:02:21 -070085 disr: option!(preceded!(punct!("="), const_expr)) >>
David Tolnayf38cdf62016-09-23 19:07:09 -070086 (Variant {
87 ident: id,
88 attrs: attrs,
89 data: data,
90 discriminant: disr,
91 })
92 ));
93
David Tolnay2f9fa632016-10-03 22:08:48 -070094 named!(pub struct_like_body -> Vec<Field>, do_parse!(
David Tolnayf38cdf62016-09-23 19:07:09 -070095 punct!("{") >>
96 fields: separated_list!(punct!(","), struct_field) >>
97 option!(punct!(",")) >>
98 punct!("}") >>
99 (fields)
100 ));
101
102 named!(tuple_like_body -> Vec<Field>, do_parse!(
103 punct!("(") >>
104 fields: separated_list!(punct!(","), tuple_field) >>
105 option!(punct!(",")) >>
106 punct!(")") >>
107 (fields)
108 ));
109
110 named!(struct_field -> Field, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700111 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700112 vis: visibility >>
113 id: ident >>
114 punct!(":") >>
115 ty: ty >>
116 (Field {
117 ident: Some(id),
118 vis: vis,
119 attrs: attrs,
120 ty: ty,
121 })
122 ));
123
124 named!(tuple_field -> Field, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700125 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700126 vis: visibility >>
127 ty: ty >>
128 (Field {
129 ident: None,
130 vis: vis,
131 attrs: attrs,
132 ty: ty,
133 })
134 ));
135
136 named!(pub visibility -> Visibility, alt!(
David Tolnaybd76e572016-10-02 13:43:16 -0700137 keyword!("pub") => { |_| Visibility::Public }
David Tolnayf38cdf62016-09-23 19:07:09 -0700138 |
139 epsilon!() => { |_| Visibility::Inherited }
140 ));
David Tolnayf38cdf62016-09-23 19:07:09 -0700141}
142
143#[cfg(feature = "printing")]
144mod printing {
145 use super::*;
David Tolnayf38cdf62016-09-23 19:07:09 -0700146 use quote::{Tokens, ToTokens};
147
148 impl ToTokens for Variant {
149 fn to_tokens(&self, tokens: &mut Tokens) {
150 for attr in &self.attrs {
151 attr.to_tokens(tokens);
152 }
153 self.ident.to_tokens(tokens);
154 self.data.to_tokens(tokens);
155 if let Some(ref disr) = self.discriminant {
156 tokens.append("=");
157 disr.to_tokens(tokens);
158 }
159 }
160 }
161
162 impl ToTokens for VariantData {
163 fn to_tokens(&self, tokens: &mut Tokens) {
164 match *self {
165 VariantData::Struct(ref fields) => {
166 tokens.append("{");
167 tokens.append_separated(fields, ",");
168 tokens.append("}");
169 }
170 VariantData::Tuple(ref fields) => {
171 tokens.append("(");
172 tokens.append_separated(fields, ",");
173 tokens.append(")");
174 }
175 VariantData::Unit => {}
176 }
177 }
178 }
179
180 impl ToTokens for Field {
181 fn to_tokens(&self, tokens: &mut Tokens) {
182 for attr in &self.attrs {
183 attr.to_tokens(tokens);
184 }
David Tolnay47a877c2016-10-01 16:50:55 -0700185 self.vis.to_tokens(tokens);
David Tolnayf38cdf62016-09-23 19:07:09 -0700186 if let Some(ref ident) = self.ident {
187 ident.to_tokens(tokens);
188 tokens.append(":");
189 }
190 self.ty.to_tokens(tokens);
191 }
192 }
193
David Tolnay47a877c2016-10-01 16:50:55 -0700194 impl ToTokens for Visibility {
195 fn to_tokens(&self, tokens: &mut Tokens) {
196 if let Visibility::Public = *self {
197 tokens.append("pub");
198 }
199 }
200 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700201}