blob: c4200958b917b2f037585770db897d072f7d24f8 [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 {
Alex Crichton62a0a592017-05-22 13:58:53 -07007 /// Attributes tagged on the variant.
8 pub attrs: Vec<Attribute>,
Clar Charrd22b5702017-03-10 15:24:56 -05009
David Tolnay4a3f59a2017-12-28 21:21:12 -050010 /// Name of the variant.
11 pub ident: Ident,
12
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`
David Tolnaye67902a2017-12-28 22:12:00 -050017 pub discriminant: Option<(Token![=], Expr)>,
Alex Crichton62a0a592017-05-22 13:58:53 -070018 }
David Tolnayf38cdf62016-09-23 19:07:09 -070019}
20
Alex Crichton62a0a592017-05-22 13:58:53 -070021ast_enum! {
22 /// Data stored within an enum variant or struct.
23 pub enum VariantData {
24 /// Struct variant, e.g. `Point { x: f64, y: f64 }`.
David Tolnay8875fca2017-12-31 13:52:37 -050025 Struct(token::Brace, Delimited<Field, Token![,]>),
Clar Charrd22b5702017-03-10 15:24:56 -050026
Alex Crichton62a0a592017-05-22 13:58:53 -070027 /// Tuple variant, e.g. `Some(T)`.
David Tolnay8875fca2017-12-31 13:52:37 -050028 Tuple(token::Paren, Delimited<Field, Token![,]>),
Clar Charrd22b5702017-03-10 15:24:56 -050029
Alex Crichton62a0a592017-05-22 13:58:53 -070030 /// Unit variant, e.g. `None`.
31 Unit,
32 }
David Tolnayf38cdf62016-09-23 19:07:09 -070033}
34
35impl VariantData {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070036 // TODO: expose this?
37 // /// Slice containing the fields stored in the variant.
David Tolnay32954ef2017-12-26 22:43:16 -050038 // pub fn fields(&self) -> &Delimited<Field, token::Comma> {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070039 // match *self {
David Tolnay8875fca2017-12-31 13:52:37 -050040 // VariantData::Struct(_, ref fields) |
41 // VariantData::Tuple(_, ref fields) => fields,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070042 // VariantData::Unit => &[],
43 // }
44 // }
45 //
46 // /// Mutable slice containing the fields stored in the variant.
David Tolnay32954ef2017-12-26 22:43:16 -050047 // pub fn fields_mut(&mut self) -> &mut Delimited<Field, token::Comma> {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070048 // match *self {
49 // VariantData::Struct(ref mut fields, _) |
50 // VariantData::Tuple(ref mut fields, _) => fields,
51 // VariantData::Unit => &mut [],
52 // }
53 // }
David Tolnayf38cdf62016-09-23 19:07:09 -070054}
55
Alex Crichton62a0a592017-05-22 13:58:53 -070056ast_struct! {
57 /// A field of a struct or enum variant.
58 pub struct Field {
David Tolnay4a3f59a2017-12-28 21:21:12 -050059 /// Attributes tagged on the field.
60 pub attrs: Vec<Attribute>,
61
62 /// Visibility of the field.
63 pub vis: Visibility,
64
Alex Crichton62a0a592017-05-22 13:58:53 -070065 /// Name of the field, if any.
66 ///
67 /// Fields of tuple structs have no names.
68 pub ident: Option<Ident>,
Clar Charrd22b5702017-03-10 15:24:56 -050069
David Tolnay4a3f59a2017-12-28 21:21:12 -050070 pub colon_token: Option<Token![:]>,
Clar Charrd22b5702017-03-10 15:24:56 -050071
Alex Crichton62a0a592017-05-22 13:58:53 -070072 /// Type of the field.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080073 pub ty: Type,
Alex Crichton62a0a592017-05-22 13:58:53 -070074 }
David Tolnayf38cdf62016-09-23 19:07:09 -070075}
76
Alex Crichtonccbb45d2017-05-23 10:58:24 -070077ast_enum_of_structs! {
Alex Crichton62a0a592017-05-22 13:58:53 -070078 /// Visibility level of an item.
79 pub enum Visibility {
80 /// Public, i.e. `pub`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -070081 pub Public(VisPublic {
David Tolnayf8db7ba2017-11-11 22:52:16 -080082 pub pub_token: Token![pub],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070083 }),
Clar Charrd22b5702017-03-10 15:24:56 -050084
Alex Crichton62a0a592017-05-22 13:58:53 -070085 /// Crate-visible, i.e. `pub(crate)`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -070086 pub Crate(VisCrate {
David Tolnayf8db7ba2017-11-11 22:52:16 -080087 pub pub_token: Token![pub],
David Tolnay32954ef2017-12-26 22:43:16 -050088 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -080089 pub crate_token: Token![crate],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070090 }),
Clar Charrd22b5702017-03-10 15:24:56 -050091
Alex Crichton62a0a592017-05-22 13:58:53 -070092 /// Restricted, e.g. `pub(self)` or `pub(super)` or `pub(in some::module)`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -070093 pub Restricted(VisRestricted {
David Tolnayf8db7ba2017-11-11 22:52:16 -080094 pub pub_token: Token![pub],
David Tolnay32954ef2017-12-26 22:43:16 -050095 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -080096 pub in_token: Option<Token![in]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070097 pub path: Box<Path>,
98 }),
Clar Charrd22b5702017-03-10 15:24:56 -050099
Alex Crichton62a0a592017-05-22 13:58:53 -0700100 /// Inherited, i.e. private.
David Tolnayfcfb9002017-12-28 22:04:29 -0500101 pub Inherited,
Alex Crichton62a0a592017-05-22 13:58:53 -0700102 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700103}
104
David Tolnayf38cdf62016-09-23 19:07:09 -0700105#[cfg(feature = "parsing")]
106pub mod parsing {
107 use super::*;
David Tolnayf38cdf62016-09-23 19:07:09 -0700108
Michael Layzell92639a52017-06-01 00:07:44 -0400109 use synom::Synom;
David Tolnayf38cdf62016-09-23 19:07:09 -0700110
Alex Crichton954046c2017-05-30 21:49:42 -0700111 impl Field {
Michael Layzell92639a52017-06-01 00:07:44 -0400112 named!(pub parse_struct -> Self, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -0500113 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400114 vis: syn!(Visibility) >>
115 id: syn!(Ident) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800116 colon: punct!(:) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800117 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400118 (Field {
119 ident: Some(id),
120 vis: vis,
121 attrs: attrs,
122 ty: ty,
123 colon_token: Some(colon),
124 })
125 ));
David Tolnayf38cdf62016-09-23 19:07:09 -0700126
Michael Layzell92639a52017-06-01 00:07:44 -0400127 named!(pub parse_tuple -> Self, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -0500128 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400129 vis: syn!(Visibility) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800130 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400131 (Field {
132 ident: None,
133 colon_token: None,
134 vis: vis,
135 attrs: attrs,
136 ty: ty,
137 })
138 ));
Michael Layzell416724e2017-05-24 21:12:34 -0400139 }
140
Alex Crichton954046c2017-05-30 21:49:42 -0700141 impl Synom for Visibility {
Michael Layzell92639a52017-06-01 00:07:44 -0400142 named!(parse -> Self, alt!(
143 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800144 pub_token: keyword!(pub) >>
145 other: parens!(keyword!(crate)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400146 (Visibility::Crate(VisCrate {
Michael Layzell92639a52017-06-01 00:07:44 -0400147 pub_token: pub_token,
David Tolnay8875fca2017-12-31 13:52:37 -0500148 paren_token: other.0,
149 crate_token: other.1,
Michael Layzell92639a52017-06-01 00:07:44 -0400150 }))
151 )
152 |
153 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800154 pub_token: keyword!(pub) >>
155 other: parens!(keyword!(self)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400156 (Visibility::Restricted(VisRestricted {
Michael Layzell92639a52017-06-01 00:07:44 -0400157 pub_token: pub_token,
David Tolnay8875fca2017-12-31 13:52:37 -0500158 paren_token: other.0,
159 in_token: None,
160 path: Box::new(other.1.into()),
Michael Layzell92639a52017-06-01 00:07:44 -0400161 }))
162 )
163 |
164 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800165 pub_token: keyword!(pub) >>
166 other: parens!(keyword!(super)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400167 (Visibility::Restricted(VisRestricted {
Michael Layzell92639a52017-06-01 00:07:44 -0400168 pub_token: pub_token,
David Tolnay8875fca2017-12-31 13:52:37 -0500169 paren_token: other.0,
170 in_token: None,
171 path: Box::new(other.1.into()),
Michael Layzell92639a52017-06-01 00:07:44 -0400172 }))
173 )
174 |
175 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800176 pub_token: keyword!(pub) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400177 other: parens!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800178 in_tok: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400179 restricted: call!(Path::parse_mod_style) >>
180 (in_tok, restricted)
181 )) >>
182 (Visibility::Restricted(VisRestricted {
Michael Layzell92639a52017-06-01 00:07:44 -0400183 pub_token: pub_token,
David Tolnay8875fca2017-12-31 13:52:37 -0500184 paren_token: other.0,
185 in_token: Some((other.1).0),
186 path: Box::new((other.1).1),
Michael Layzell92639a52017-06-01 00:07:44 -0400187 }))
188 )
189 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800190 keyword!(pub) => { |tok| {
Michael Layzell92639a52017-06-01 00:07:44 -0400191 Visibility::Public(VisPublic {
192 pub_token: tok,
193 })
194 } }
195 |
David Tolnayfcfb9002017-12-28 22:04:29 -0500196 epsilon!() => { |_| Visibility::Inherited }
Michael Layzell92639a52017-06-01 00:07:44 -0400197 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800198
199 fn description() -> Option<&'static str> {
200 Some("visibility qualifier, e.g. `pub`")
201 }
Alex Crichton954046c2017-05-30 21:49:42 -0700202 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700203}
204
205#[cfg(feature = "printing")]
206mod printing {
207 use super::*;
David Tolnay51382052017-12-27 13:46:21 -0500208 use quote::{ToTokens, Tokens};
David Tolnayf38cdf62016-09-23 19:07:09 -0700209
210 impl ToTokens for Variant {
211 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700212 tokens.append_all(&self.attrs);
David Tolnayf38cdf62016-09-23 19:07:09 -0700213 self.ident.to_tokens(tokens);
214 self.data.to_tokens(tokens);
David Tolnaye67902a2017-12-28 22:12:00 -0500215 if let Some((ref eq_token, ref disc)) = self.discriminant {
216 eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400217 disc.to_tokens(tokens);
218 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700219 }
220 }
221
222 impl ToTokens for VariantData {
223 fn to_tokens(&self, tokens: &mut Tokens) {
224 match *self {
David Tolnay8875fca2017-12-31 13:52:37 -0500225 VariantData::Struct(ref brace, ref fields) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700226 brace.surround(tokens, |tokens| {
227 fields.to_tokens(tokens);
228 });
David Tolnayf38cdf62016-09-23 19:07:09 -0700229 }
David Tolnay8875fca2017-12-31 13:52:37 -0500230 VariantData::Tuple(ref paren, ref fields) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700231 paren.surround(tokens, |tokens| {
232 fields.to_tokens(tokens);
233 });
David Tolnayf38cdf62016-09-23 19:07:09 -0700234 }
235 VariantData::Unit => {}
236 }
237 }
238 }
239
240 impl ToTokens for Field {
241 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700242 tokens.append_all(&self.attrs);
David Tolnay47a877c2016-10-01 16:50:55 -0700243 self.vis.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400244 if let Some(ref ident) = self.ident {
245 ident.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -0700246 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400247 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700248 self.ty.to_tokens(tokens);
249 }
250 }
251
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700252 impl ToTokens for VisPublic {
David Tolnay47a877c2016-10-01 16:50:55 -0700253 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700254 self.pub_token.to_tokens(tokens)
255 }
256 }
Arnaviond32b2942017-04-29 17:18:02 -0700257
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700258 impl ToTokens for VisCrate {
259 fn to_tokens(&self, tokens: &mut Tokens) {
260 self.pub_token.to_tokens(tokens);
261 self.paren_token.surround(tokens, |tokens| {
262 self.crate_token.to_tokens(tokens);
263 })
264 }
265 }
Arnaviond32b2942017-04-29 17:18:02 -0700266
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700267 impl ToTokens for VisRestricted {
268 fn to_tokens(&self, tokens: &mut Tokens) {
269 self.pub_token.to_tokens(tokens);
270 self.paren_token.surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400271 // XXX: If we have a path which is not "self" or "super",
272 // automatically add the "in" token.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700273 self.in_token.to_tokens(tokens);
274 self.path.to_tokens(tokens);
275 });
276 }
277 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700278}