blob: 5085986116bc8ebedcb8c432b8359dcb3bbc190d [file] [log] [blame]
David Tolnayf38cdf62016-09-23 19:07:09 -07001use super::*;
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002use delimited::Delimited;
David Tolnayf38cdf62016-09-23 19:07:09 -07003
Alex Crichton62a0a592017-05-22 13:58:53 -07004ast_struct! {
5 /// An enum variant.
6 pub struct Variant {
7 /// Name of the variant.
8 pub ident: Ident,
Clar Charrd22b5702017-03-10 15:24:56 -05009
Alex Crichton62a0a592017-05-22 13:58:53 -070010 /// Attributes tagged on the variant.
11 pub attrs: Vec<Attribute>,
Clar Charrd22b5702017-03-10 15:24:56 -050012
Alex Crichton62a0a592017-05-22 13:58:53 -070013 /// Type of variant.
14 pub data: VariantData,
Clar Charrd22b5702017-03-10 15:24:56 -050015
Alex Crichton62a0a592017-05-22 13:58:53 -070016 /// Explicit discriminant, e.g. `Foo = 1`
17 pub discriminant: Option<ConstExpr>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070018
19 pub eq_token: Option<tokens::Eq>,
Alex Crichton62a0a592017-05-22 13:58:53 -070020 }
David Tolnayf38cdf62016-09-23 19:07:09 -070021}
22
Alex Crichton62a0a592017-05-22 13:58:53 -070023ast_enum! {
24 /// Data stored within an enum variant or struct.
25 pub enum VariantData {
26 /// Struct variant, e.g. `Point { x: f64, y: f64 }`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -070027 Struct(Delimited<Field, tokens::Comma>, tokens::Brace),
Clar Charrd22b5702017-03-10 15:24:56 -050028
Alex Crichton62a0a592017-05-22 13:58:53 -070029 /// Tuple variant, e.g. `Some(T)`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -070030 Tuple(Delimited<Field, tokens::Comma>, tokens::Paren),
Clar Charrd22b5702017-03-10 15:24:56 -050031
Alex Crichton62a0a592017-05-22 13:58:53 -070032 /// Unit variant, e.g. `None`.
33 Unit,
34 }
David Tolnayf38cdf62016-09-23 19:07:09 -070035}
36
37impl VariantData {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070038 // TODO: expose this?
39 // /// Slice containing the fields stored in the variant.
40 // pub fn fields(&self) -> &Delimited<Field, tokens::Comma> {
41 // match *self {
42 // VariantData::Struct(ref fields, _) |
43 // VariantData::Tuple(ref fields, _) => fields,
44 // VariantData::Unit => &[],
45 // }
46 // }
47 //
48 // /// Mutable slice containing the fields stored in the variant.
49 // pub fn fields_mut(&mut self) -> &mut Delimited<Field, tokens::Comma> {
50 // match *self {
51 // VariantData::Struct(ref mut fields, _) |
52 // VariantData::Tuple(ref mut fields, _) => fields,
53 // VariantData::Unit => &mut [],
54 // }
55 // }
David Tolnayf38cdf62016-09-23 19:07:09 -070056}
57
Alex Crichton62a0a592017-05-22 13:58:53 -070058ast_struct! {
59 /// A field of a struct or enum variant.
60 pub struct Field {
61 /// Name of the field, if any.
62 ///
63 /// Fields of tuple structs have no names.
64 pub ident: Option<Ident>,
Clar Charrd22b5702017-03-10 15:24:56 -050065
Alex Crichton62a0a592017-05-22 13:58:53 -070066 /// Visibility of the field.
67 pub vis: Visibility,
Clar Charrd22b5702017-03-10 15:24:56 -050068
Alex Crichton62a0a592017-05-22 13:58:53 -070069 /// Attributes tagged on the field.
70 pub attrs: Vec<Attribute>,
Clar Charrd22b5702017-03-10 15:24:56 -050071
Alex Crichton62a0a592017-05-22 13:58:53 -070072 /// Type of the field.
73 pub ty: Ty,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070074
75 pub colon_token: Option<tokens::Colon>,
Alex Crichton62a0a592017-05-22 13:58:53 -070076 }
David Tolnayf38cdf62016-09-23 19:07:09 -070077}
78
Alex Crichtonccbb45d2017-05-23 10:58:24 -070079ast_enum_of_structs! {
Alex Crichton62a0a592017-05-22 13:58:53 -070080 /// Visibility level of an item.
81 pub enum Visibility {
82 /// Public, i.e. `pub`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -070083 pub Public(VisPublic {
84 pub pub_token: tokens::Pub,
85 }),
Clar Charrd22b5702017-03-10 15:24:56 -050086
Alex Crichton62a0a592017-05-22 13:58:53 -070087 /// Crate-visible, i.e. `pub(crate)`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -070088 pub Crate(VisCrate {
89 pub pub_token: tokens::Pub,
90 pub paren_token: tokens::Paren,
91 pub crate_token: tokens::Crate,
92 }),
Clar Charrd22b5702017-03-10 15:24:56 -050093
Alex Crichton62a0a592017-05-22 13:58:53 -070094 /// Restricted, e.g. `pub(self)` or `pub(super)` or `pub(in some::module)`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -070095 pub Restricted(VisRestricted {
96 pub pub_token: tokens::Pub,
97 pub paren_token: tokens::Paren,
98 pub in_token: Option<tokens::In>,
99 pub path: Box<Path>,
100 }),
Clar Charrd22b5702017-03-10 15:24:56 -0500101
Alex Crichton62a0a592017-05-22 13:58:53 -0700102 /// Inherited, i.e. private.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700103 pub Inherited(VisInherited {}),
Alex Crichton62a0a592017-05-22 13:58:53 -0700104 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700105}
106
David Tolnayf38cdf62016-09-23 19:07:09 -0700107#[cfg(feature = "parsing")]
108pub mod parsing {
109 use super::*;
David Tolnay28c1db62016-10-27 22:48:18 -0700110 use WhereClause;
David Tolnay514f1292017-02-27 12:30:57 -0800111 #[cfg(feature = "full")]
112 use ConstExpr;
David Tolnay4a51dc72016-10-01 00:40:31 -0700113 use attr::parsing::outer_attr;
David Tolnayf945fb52017-02-27 12:53:54 -0800114 #[cfg(feature = "full")]
David Tolnay3cb23a92016-10-07 23:02:21 -0700115 use constant::parsing::const_expr;
David Tolnay514f1292017-02-27 12:30:57 -0800116 #[cfg(feature = "full")]
117 use expr::parsing::expr;
David Tolnay28c1db62016-10-27 22:48:18 -0700118 use generics::parsing::where_clause;
David Tolnayf38cdf62016-09-23 19:07:09 -0700119 use ident::parsing::ident;
Arnaviond32b2942017-04-29 17:18:02 -0700120 use ty::parsing::{mod_style_path, ty};
David Tolnayf38cdf62016-09-23 19:07:09 -0700121
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700122 named!(pub struct_body -> (WhereClause, VariantData, Option<tokens::Semi>), alt!(
David Tolnay28c1db62016-10-27 22:48:18 -0700123 do_parse!(
124 wh: where_clause >>
125 body: struct_like_body >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700126 (wh, VariantData::Struct(body.0, body.1), None)
David Tolnay28c1db62016-10-27 22:48:18 -0700127 )
David Tolnayf38cdf62016-09-23 19:07:09 -0700128 |
David Tolnay28c1db62016-10-27 22:48:18 -0700129 do_parse!(
130 body: tuple_like_body >>
131 wh: where_clause >>
132 punct!(";") >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700133 (wh, VariantData::Tuple(body.0, body.1), Some(tokens::Semi::default()))
David Tolnay28c1db62016-10-27 22:48:18 -0700134 )
David Tolnayf38cdf62016-09-23 19:07:09 -0700135 |
David Tolnay28c1db62016-10-27 22:48:18 -0700136 do_parse!(
137 wh: where_clause >>
138 punct!(";") >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700139 (wh, VariantData::Unit, Some(tokens::Semi::default()))
David Tolnay28c1db62016-10-27 22:48:18 -0700140 )
David Tolnayf38cdf62016-09-23 19:07:09 -0700141 ));
142
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700143 named!(pub enum_body -> (WhereClause, Delimited<Variant, tokens::Comma>, tokens::Brace), do_parse!(
David Tolnay28c1db62016-10-27 22:48:18 -0700144 wh: where_clause >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700145 punct!("{") >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700146 variants: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
147 variant) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700148 punct!("}") >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700149 (wh, variants, tokens::Brace::default())
David Tolnayf38cdf62016-09-23 19:07:09 -0700150 ));
151
152 named!(variant -> Variant, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700153 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700154 id: ident >>
155 data: alt!(
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700156 struct_like_body => { |(d, b)| VariantData::Struct(d, b) }
David Tolnayf38cdf62016-09-23 19:07:09 -0700157 |
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700158 tuple_like_body => { |(d, b)| VariantData::Tuple(d, b) }
David Tolnayf38cdf62016-09-23 19:07:09 -0700159 |
160 epsilon!() => { |_| VariantData::Unit }
161 ) >>
David Tolnay514f1292017-02-27 12:30:57 -0800162 disr: option!(preceded!(punct!("="), discriminant)) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700163 (Variant {
164 ident: id,
165 attrs: attrs,
166 data: data,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700167 eq_token: disr.as_ref().map(|_| tokens::Eq::default()),
David Tolnayf38cdf62016-09-23 19:07:09 -0700168 discriminant: disr,
169 })
170 ));
171
David Tolnay514f1292017-02-27 12:30:57 -0800172 #[cfg(not(feature = "full"))]
David Tolnayf945fb52017-02-27 12:53:54 -0800173 use constant::parsing::const_expr as discriminant;
David Tolnay514f1292017-02-27 12:30:57 -0800174
175 #[cfg(feature = "full")]
176 named!(discriminant -> ConstExpr, alt!(
177 terminated!(const_expr, after_discriminant)
178 |
179 terminated!(expr, after_discriminant) => { ConstExpr::Other }
180 ));
181
182 #[cfg(feature = "full")]
183 named!(after_discriminant -> &str, peek!(alt!(punct!(",") | punct!("}"))));
184
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700185 named!(pub struct_like_body -> (Delimited<Field, tokens::Comma>, tokens::Brace), do_parse!(
David Tolnayf38cdf62016-09-23 19:07:09 -0700186 punct!("{") >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700187 fields: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
188 struct_field) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700189 punct!("}") >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700190 (fields, tokens::Brace::default())
David Tolnayf38cdf62016-09-23 19:07:09 -0700191 ));
192
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700193 named!(tuple_like_body -> (Delimited<Field, tokens::Comma>, tokens::Paren), do_parse!(
David Tolnayf38cdf62016-09-23 19:07:09 -0700194 punct!("(") >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700195 fields: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
196 tuple_field) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700197 punct!(")") >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700198 (fields, tokens::Paren::default())
David Tolnayf38cdf62016-09-23 19:07:09 -0700199 ));
200
201 named!(struct_field -> Field, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700202 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700203 vis: visibility >>
204 id: ident >>
205 punct!(":") >>
206 ty: ty >>
207 (Field {
208 ident: Some(id),
209 vis: vis,
210 attrs: attrs,
211 ty: ty,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700212 colon_token: Some(tokens::Colon::default()),
David Tolnayf38cdf62016-09-23 19:07:09 -0700213 })
214 ));
215
216 named!(tuple_field -> Field, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700217 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700218 vis: visibility >>
219 ty: ty >>
220 (Field {
221 ident: None,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700222 colon_token: None,
David Tolnayf38cdf62016-09-23 19:07:09 -0700223 vis: vis,
224 attrs: attrs,
225 ty: ty,
226 })
227 ));
228
229 named!(pub visibility -> Visibility, alt!(
David Tolnaye07f9e02016-10-30 17:05:55 -0700230 do_parse!(
231 keyword!("pub") >>
232 punct!("(") >>
233 keyword!("crate") >>
234 punct!(")") >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700235 (Visibility::Crate(VisCrate {
236 crate_token: tokens::Crate::default(),
237 paren_token: tokens::Paren::default(),
238 pub_token: tokens::Pub::default(),
239 }))
David Tolnaye07f9e02016-10-30 17:05:55 -0700240 )
241 |
242 do_parse!(
243 keyword!("pub") >>
244 punct!("(") >>
Arnaviond32b2942017-04-29 17:18:02 -0700245 keyword!("self") >>
246 punct!(")") >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700247 (Visibility::Restricted(VisRestricted {
248 path: Box::new("self".into()),
249 in_token: None,
250 paren_token: tokens::Paren::default(),
251 pub_token: tokens::Pub::default(),
252 }))
Arnaviond32b2942017-04-29 17:18:02 -0700253 )
254 |
255 do_parse!(
256 keyword!("pub") >>
257 punct!("(") >>
258 keyword!("super") >>
259 punct!(")") >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700260 (Visibility::Restricted(VisRestricted {
261 path: Box::new("super".into()),
262 in_token: None,
263 paren_token: tokens::Paren::default(),
264 pub_token: tokens::Pub::default(),
265 }))
Arnaviond32b2942017-04-29 17:18:02 -0700266 )
267 |
268 do_parse!(
269 keyword!("pub") >>
270 punct!("(") >>
271 keyword!("in") >>
272 restricted: mod_style_path >>
David Tolnaye07f9e02016-10-30 17:05:55 -0700273 punct!(")") >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700274 (Visibility::Restricted(VisRestricted {
275 path: Box::new(restricted),
276 in_token: Some(tokens::In::default()),
277 paren_token: tokens::Paren::default(),
278 pub_token: tokens::Pub::default(),
279 }))
David Tolnaye07f9e02016-10-30 17:05:55 -0700280 )
281 |
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700282 keyword!("pub") => { |_| {
283 Visibility::Public(VisPublic {
284 pub_token: tokens::Pub::default(),
285 })
286 } }
David Tolnayf38cdf62016-09-23 19:07:09 -0700287 |
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700288 epsilon!() => { |_| Visibility::Inherited(VisInherited {}) }
David Tolnayf38cdf62016-09-23 19:07:09 -0700289 ));
David Tolnayf38cdf62016-09-23 19:07:09 -0700290}
291
292#[cfg(feature = "printing")]
293mod printing {
294 use super::*;
David Tolnayf38cdf62016-09-23 19:07:09 -0700295 use quote::{Tokens, ToTokens};
296
297 impl ToTokens for Variant {
298 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700299 tokens.append_all(&self.attrs);
David Tolnayf38cdf62016-09-23 19:07:09 -0700300 self.ident.to_tokens(tokens);
301 self.data.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700302 self.eq_token.to_tokens(tokens);
303 self.discriminant.to_tokens(tokens);
David Tolnayf38cdf62016-09-23 19:07:09 -0700304 }
305 }
306
307 impl ToTokens for VariantData {
308 fn to_tokens(&self, tokens: &mut Tokens) {
309 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700310 VariantData::Struct(ref fields, ref brace) => {
311 brace.surround(tokens, |tokens| {
312 fields.to_tokens(tokens);
313 });
David Tolnayf38cdf62016-09-23 19:07:09 -0700314 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700315 VariantData::Tuple(ref fields, ref paren) => {
316 paren.surround(tokens, |tokens| {
317 fields.to_tokens(tokens);
318 });
David Tolnayf38cdf62016-09-23 19:07:09 -0700319 }
320 VariantData::Unit => {}
321 }
322 }
323 }
324
325 impl ToTokens for Field {
326 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700327 tokens.append_all(&self.attrs);
David Tolnay47a877c2016-10-01 16:50:55 -0700328 self.vis.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700329 self.ident.to_tokens(tokens);
330 self.colon_token.to_tokens(tokens);
David Tolnayf38cdf62016-09-23 19:07:09 -0700331 self.ty.to_tokens(tokens);
332 }
333 }
334
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700335 impl ToTokens for VisPublic {
David Tolnay47a877c2016-10-01 16:50:55 -0700336 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700337 self.pub_token.to_tokens(tokens)
338 }
339 }
Arnaviond32b2942017-04-29 17:18:02 -0700340
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700341 impl ToTokens for VisCrate {
342 fn to_tokens(&self, tokens: &mut Tokens) {
343 self.pub_token.to_tokens(tokens);
344 self.paren_token.surround(tokens, |tokens| {
345 self.crate_token.to_tokens(tokens);
346 })
347 }
348 }
Arnaviond32b2942017-04-29 17:18:02 -0700349
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700350 impl ToTokens for VisRestricted {
351 fn to_tokens(&self, tokens: &mut Tokens) {
352 self.pub_token.to_tokens(tokens);
353 self.paren_token.surround(tokens, |tokens| {
354 self.in_token.to_tokens(tokens);
355 self.path.to_tokens(tokens);
356 });
357 }
358 }
Arnaviond32b2942017-04-29 17:18:02 -0700359
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700360 impl ToTokens for VisInherited {
361 fn to_tokens(&self, _tokens: &mut Tokens) {
David Tolnay47a877c2016-10-01 16:50:55 -0700362 }
363 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700364}