blob: 3a7c025c827f69294476d5a5e7d790752d2b025f [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
David Tolnay4a3f59a2017-12-28 21:21:12 -050016 pub eq_token: Option<Token![=]>,
17
Alex Crichton62a0a592017-05-22 13:58:53 -070018 /// Explicit discriminant, e.g. `Foo = 1`
Michael Layzelld7ee9102017-06-07 10:02:19 -040019 pub discriminant: Option<Expr>,
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 }`.
David Tolnay32954ef2017-12-26 22:43:16 -050027 Struct(Delimited<Field, Token![,]>, token::Brace),
Clar Charrd22b5702017-03-10 15:24:56 -050028
Alex Crichton62a0a592017-05-22 13:58:53 -070029 /// Tuple variant, e.g. `Some(T)`.
David Tolnay32954ef2017-12-26 22:43:16 -050030 Tuple(Delimited<Field, Token![,]>, token::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.
David Tolnay32954ef2017-12-26 22:43:16 -050040 // pub fn fields(&self) -> &Delimited<Field, token::Comma> {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070041 // 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.
David Tolnay32954ef2017-12-26 22:43:16 -050049 // pub fn fields_mut(&mut self) -> &mut Delimited<Field, token::Comma> {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070050 // 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 {
David Tolnay4a3f59a2017-12-28 21:21:12 -050061 /// Attributes tagged on the field.
62 pub attrs: Vec<Attribute>,
63
64 /// Visibility of the field.
65 pub vis: Visibility,
66
Alex Crichton62a0a592017-05-22 13:58:53 -070067 /// Name of the field, if any.
68 ///
69 /// Fields of tuple structs have no names.
70 pub ident: Option<Ident>,
Clar Charrd22b5702017-03-10 15:24:56 -050071
David Tolnay4a3f59a2017-12-28 21:21:12 -050072 pub colon_token: Option<Token![:]>,
Clar Charrd22b5702017-03-10 15:24:56 -050073
Alex Crichton62a0a592017-05-22 13:58:53 -070074 /// Type of the field.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080075 pub ty: Type,
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 {
David Tolnayf8db7ba2017-11-11 22:52:16 -080084 pub pub_token: Token![pub],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070085 }),
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 {
David Tolnayf8db7ba2017-11-11 22:52:16 -080089 pub pub_token: Token![pub],
David Tolnay32954ef2017-12-26 22:43:16 -050090 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -080091 pub crate_token: Token![crate],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070092 }),
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 {
David Tolnayf8db7ba2017-11-11 22:52:16 -080096 pub pub_token: Token![pub],
David Tolnay32954ef2017-12-26 22:43:16 -050097 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -080098 pub in_token: Option<Token![in]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070099 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 Tolnayf38cdf62016-09-23 19:07:09 -0700110
Michael Layzell92639a52017-06-01 00:07:44 -0400111 use synom::Synom;
David Tolnayf38cdf62016-09-23 19:07:09 -0700112
Alex Crichton954046c2017-05-30 21:49:42 -0700113 impl Field {
Michael Layzell92639a52017-06-01 00:07:44 -0400114 named!(pub parse_struct -> Self, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -0500115 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400116 vis: syn!(Visibility) >>
117 id: syn!(Ident) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800118 colon: punct!(:) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800119 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400120 (Field {
121 ident: Some(id),
122 vis: vis,
123 attrs: attrs,
124 ty: ty,
125 colon_token: Some(colon),
126 })
127 ));
David Tolnayf38cdf62016-09-23 19:07:09 -0700128
Michael Layzell92639a52017-06-01 00:07:44 -0400129 named!(pub parse_tuple -> Self, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -0500130 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400131 vis: syn!(Visibility) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800132 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400133 (Field {
134 ident: None,
135 colon_token: None,
136 vis: vis,
137 attrs: attrs,
138 ty: ty,
139 })
140 ));
Michael Layzell416724e2017-05-24 21:12:34 -0400141 }
142
Alex Crichton954046c2017-05-30 21:49:42 -0700143 impl Synom for Visibility {
Michael Layzell92639a52017-06-01 00:07:44 -0400144 named!(parse -> Self, alt!(
145 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800146 pub_token: keyword!(pub) >>
147 other: parens!(keyword!(crate)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400148 (Visibility::Crate(VisCrate {
149 crate_token: other.0,
150 paren_token: other.1,
151 pub_token: pub_token,
152 }))
153 )
154 |
155 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800156 pub_token: keyword!(pub) >>
157 other: parens!(keyword!(self)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400158 (Visibility::Restricted(VisRestricted {
159 path: Box::new(other.0.into()),
160 in_token: None,
161 paren_token: other.1,
162 pub_token: pub_token,
163 }))
164 )
165 |
166 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800167 pub_token: keyword!(pub) >>
168 other: parens!(keyword!(super)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400169 (Visibility::Restricted(VisRestricted {
170 path: Box::new(other.0.into()),
171 in_token: None,
172 paren_token: other.1,
173 pub_token: pub_token,
174 }))
175 )
176 |
177 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800178 pub_token: keyword!(pub) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400179 other: parens!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800180 in_tok: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400181 restricted: call!(Path::parse_mod_style) >>
182 (in_tok, restricted)
183 )) >>
184 (Visibility::Restricted(VisRestricted {
185 path: Box::new((other.0).1),
186 in_token: Some((other.0).0),
187 paren_token: other.1,
188 pub_token: pub_token,
189 }))
190 )
191 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800192 keyword!(pub) => { |tok| {
Michael Layzell92639a52017-06-01 00:07:44 -0400193 Visibility::Public(VisPublic {
194 pub_token: tok,
195 })
196 } }
197 |
198 epsilon!() => { |_| Visibility::Inherited(VisInherited {}) }
199 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700200 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700201}
202
203#[cfg(feature = "printing")]
204mod printing {
205 use super::*;
David Tolnay51382052017-12-27 13:46:21 -0500206 use quote::{ToTokens, Tokens};
David Tolnayf38cdf62016-09-23 19:07:09 -0700207
208 impl ToTokens for Variant {
209 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700210 tokens.append_all(&self.attrs);
David Tolnayf38cdf62016-09-23 19:07:09 -0700211 self.ident.to_tokens(tokens);
212 self.data.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400213 if let Some(ref disc) = self.discriminant {
Alex Crichton259ee532017-07-14 06:51:02 -0700214 TokensOrDefault(&self.eq_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400215 disc.to_tokens(tokens);
216 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700217 }
218 }
219
220 impl ToTokens for VariantData {
221 fn to_tokens(&self, tokens: &mut Tokens) {
222 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700223 VariantData::Struct(ref fields, ref brace) => {
224 brace.surround(tokens, |tokens| {
225 fields.to_tokens(tokens);
226 });
David Tolnayf38cdf62016-09-23 19:07:09 -0700227 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700228 VariantData::Tuple(ref fields, ref paren) => {
229 paren.surround(tokens, |tokens| {
230 fields.to_tokens(tokens);
231 });
David Tolnayf38cdf62016-09-23 19:07:09 -0700232 }
233 VariantData::Unit => {}
234 }
235 }
236 }
237
238 impl ToTokens for Field {
239 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700240 tokens.append_all(&self.attrs);
David Tolnay47a877c2016-10-01 16:50:55 -0700241 self.vis.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400242 if let Some(ref ident) = self.ident {
243 ident.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -0700244 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400245 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700246 self.ty.to_tokens(tokens);
247 }
248 }
249
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700250 impl ToTokens for VisPublic {
David Tolnay47a877c2016-10-01 16:50:55 -0700251 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700252 self.pub_token.to_tokens(tokens)
253 }
254 }
Arnaviond32b2942017-04-29 17:18:02 -0700255
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700256 impl ToTokens for VisCrate {
257 fn to_tokens(&self, tokens: &mut Tokens) {
258 self.pub_token.to_tokens(tokens);
259 self.paren_token.surround(tokens, |tokens| {
260 self.crate_token.to_tokens(tokens);
261 })
262 }
263 }
Arnaviond32b2942017-04-29 17:18:02 -0700264
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700265 impl ToTokens for VisRestricted {
266 fn to_tokens(&self, tokens: &mut Tokens) {
267 self.pub_token.to_tokens(tokens);
268 self.paren_token.surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400269 // XXX: If we have a path which is not "self" or "super",
270 // automatically add the "in" token.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700271 self.in_token.to_tokens(tokens);
272 self.path.to_tokens(tokens);
273 });
274 }
275 }
Arnaviond32b2942017-04-29 17:18:02 -0700276
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700277 impl ToTokens for VisInherited {
David Tolnay51382052017-12-27 13:46:21 -0500278 fn to_tokens(&self, _tokens: &mut Tokens) {}
David Tolnay47a877c2016-10-01 16:50:55 -0700279 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700280}