blob: a1cf522dd0dd7031b406d5f9f3fdf36ca13e4b3e [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
Michael Layzell416724e2017-05-24 21:12:34 -0400182 // XXX: HACKY
David Tolnay514f1292017-02-27 12:30:57 -0800183 #[cfg(feature = "full")]
Michael Layzell416724e2017-05-24 21:12:34 -0400184 pub fn eof(input: &[synom::TokenTree]) -> synom::IResult<&[synom::TokenTree], &'static str> {
185 if input.is_empty() {
186 synom::IResult::Done(&[], "")
187 } else {
188 synom::IResult::Error
189 }
190 }
191
192 #[cfg(feature = "full")]
193 named!(after_discriminant -> &str, peek!(alt!(punct!(",") | input_end!())));
David Tolnay514f1292017-02-27 12:30:57 -0800194
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700195 named!(pub struct_like_body -> (Delimited<Field, tokens::Comma>, tokens::Brace), do_parse!(
David Tolnayf38cdf62016-09-23 19:07:09 -0700196 punct!("{") >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700197 fields: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
198 struct_field) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700199 punct!("}") >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700200 (fields, tokens::Brace::default())
David Tolnayf38cdf62016-09-23 19:07:09 -0700201 ));
202
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700203 named!(tuple_like_body -> (Delimited<Field, tokens::Comma>, tokens::Paren), do_parse!(
David Tolnayf38cdf62016-09-23 19:07:09 -0700204 punct!("(") >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700205 fields: terminated_list!(map!(punct!(","), |_| tokens::Comma::default()),
206 tuple_field) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700207 punct!(")") >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700208 (fields, tokens::Paren::default())
David Tolnayf38cdf62016-09-23 19:07:09 -0700209 ));
210
211 named!(struct_field -> Field, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700212 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700213 vis: visibility >>
214 id: ident >>
215 punct!(":") >>
216 ty: ty >>
217 (Field {
218 ident: Some(id),
219 vis: vis,
220 attrs: attrs,
221 ty: ty,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700222 colon_token: Some(tokens::Colon::default()),
David Tolnayf38cdf62016-09-23 19:07:09 -0700223 })
224 ));
225
226 named!(tuple_field -> Field, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700227 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700228 vis: visibility >>
229 ty: ty >>
230 (Field {
231 ident: None,
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700232 colon_token: None,
David Tolnayf38cdf62016-09-23 19:07:09 -0700233 vis: vis,
234 attrs: attrs,
235 ty: ty,
236 })
237 ));
238
239 named!(pub visibility -> Visibility, alt!(
David Tolnaye07f9e02016-10-30 17:05:55 -0700240 do_parse!(
241 keyword!("pub") >>
242 punct!("(") >>
243 keyword!("crate") >>
244 punct!(")") >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700245 (Visibility::Crate(VisCrate {
246 crate_token: tokens::Crate::default(),
247 paren_token: tokens::Paren::default(),
248 pub_token: tokens::Pub::default(),
249 }))
David Tolnaye07f9e02016-10-30 17:05:55 -0700250 )
251 |
252 do_parse!(
253 keyword!("pub") >>
254 punct!("(") >>
Arnaviond32b2942017-04-29 17:18:02 -0700255 keyword!("self") >>
256 punct!(")") >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700257 (Visibility::Restricted(VisRestricted {
258 path: Box::new("self".into()),
259 in_token: None,
260 paren_token: tokens::Paren::default(),
261 pub_token: tokens::Pub::default(),
262 }))
Arnaviond32b2942017-04-29 17:18:02 -0700263 )
264 |
265 do_parse!(
266 keyword!("pub") >>
267 punct!("(") >>
268 keyword!("super") >>
269 punct!(")") >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700270 (Visibility::Restricted(VisRestricted {
271 path: Box::new("super".into()),
272 in_token: None,
273 paren_token: tokens::Paren::default(),
274 pub_token: tokens::Pub::default(),
275 }))
Arnaviond32b2942017-04-29 17:18:02 -0700276 )
277 |
278 do_parse!(
279 keyword!("pub") >>
280 punct!("(") >>
281 keyword!("in") >>
282 restricted: mod_style_path >>
David Tolnaye07f9e02016-10-30 17:05:55 -0700283 punct!(")") >>
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700284 (Visibility::Restricted(VisRestricted {
285 path: Box::new(restricted),
286 in_token: Some(tokens::In::default()),
287 paren_token: tokens::Paren::default(),
288 pub_token: tokens::Pub::default(),
289 }))
David Tolnaye07f9e02016-10-30 17:05:55 -0700290 )
291 |
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700292 keyword!("pub") => { |_| {
293 Visibility::Public(VisPublic {
294 pub_token: tokens::Pub::default(),
295 })
296 } }
David Tolnayf38cdf62016-09-23 19:07:09 -0700297 |
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700298 epsilon!() => { |_| Visibility::Inherited(VisInherited {}) }
David Tolnayf38cdf62016-09-23 19:07:09 -0700299 ));
David Tolnayf38cdf62016-09-23 19:07:09 -0700300}
301
302#[cfg(feature = "printing")]
303mod printing {
304 use super::*;
David Tolnayf38cdf62016-09-23 19:07:09 -0700305 use quote::{Tokens, ToTokens};
306
307 impl ToTokens for Variant {
308 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700309 tokens.append_all(&self.attrs);
David Tolnayf38cdf62016-09-23 19:07:09 -0700310 self.ident.to_tokens(tokens);
311 self.data.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700312 self.eq_token.to_tokens(tokens);
313 self.discriminant.to_tokens(tokens);
David Tolnayf38cdf62016-09-23 19:07:09 -0700314 }
315 }
316
317 impl ToTokens for VariantData {
318 fn to_tokens(&self, tokens: &mut Tokens) {
319 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700320 VariantData::Struct(ref fields, ref brace) => {
321 brace.surround(tokens, |tokens| {
322 fields.to_tokens(tokens);
323 });
David Tolnayf38cdf62016-09-23 19:07:09 -0700324 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700325 VariantData::Tuple(ref fields, ref paren) => {
326 paren.surround(tokens, |tokens| {
327 fields.to_tokens(tokens);
328 });
David Tolnayf38cdf62016-09-23 19:07:09 -0700329 }
330 VariantData::Unit => {}
331 }
332 }
333 }
334
335 impl ToTokens for Field {
336 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700337 tokens.append_all(&self.attrs);
David Tolnay47a877c2016-10-01 16:50:55 -0700338 self.vis.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700339 self.ident.to_tokens(tokens);
340 self.colon_token.to_tokens(tokens);
David Tolnayf38cdf62016-09-23 19:07:09 -0700341 self.ty.to_tokens(tokens);
342 }
343 }
344
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700345 impl ToTokens for VisPublic {
David Tolnay47a877c2016-10-01 16:50:55 -0700346 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700347 self.pub_token.to_tokens(tokens)
348 }
349 }
Arnaviond32b2942017-04-29 17:18:02 -0700350
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700351 impl ToTokens for VisCrate {
352 fn to_tokens(&self, tokens: &mut Tokens) {
353 self.pub_token.to_tokens(tokens);
354 self.paren_token.surround(tokens, |tokens| {
355 self.crate_token.to_tokens(tokens);
356 })
357 }
358 }
Arnaviond32b2942017-04-29 17:18:02 -0700359
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700360 impl ToTokens for VisRestricted {
361 fn to_tokens(&self, tokens: &mut Tokens) {
362 self.pub_token.to_tokens(tokens);
363 self.paren_token.surround(tokens, |tokens| {
364 self.in_token.to_tokens(tokens);
365 self.path.to_tokens(tokens);
366 });
367 }
368 }
Arnaviond32b2942017-04-29 17:18:02 -0700369
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700370 impl ToTokens for VisInherited {
371 fn to_tokens(&self, _tokens: &mut Tokens) {
David Tolnay47a877c2016-10-01 16:50:55 -0700372 }
373 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700374}