blob: a860ce4b307ab056e1626a35ef16f4c9375d0293 [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 Tolnay32954ef2017-12-26 22:43:16 -050025 Struct(Delimited<Field, Token![,]>, token::Brace),
Clar Charrd22b5702017-03-10 15:24:56 -050026
Alex Crichton62a0a592017-05-22 13:58:53 -070027 /// Tuple variant, e.g. `Some(T)`.
David Tolnay32954ef2017-12-26 22:43:16 -050028 Tuple(Delimited<Field, Token![,]>, token::Paren),
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 {
40 // VariantData::Struct(ref fields, _) |
41 // VariantData::Tuple(ref fields, _) => fields,
42 // 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 {
147 crate_token: other.0,
148 paren_token: other.1,
149 pub_token: pub_token,
150 }))
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 {
157 path: Box::new(other.0.into()),
158 in_token: None,
159 paren_token: other.1,
160 pub_token: pub_token,
161 }))
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 {
168 path: Box::new(other.0.into()),
169 in_token: None,
170 paren_token: other.1,
171 pub_token: pub_token,
172 }))
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 {
183 path: Box::new((other.0).1),
184 in_token: Some((other.0).0),
185 paren_token: other.1,
186 pub_token: pub_token,
187 }))
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 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700198 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700199}
200
201#[cfg(feature = "printing")]
202mod printing {
203 use super::*;
David Tolnay51382052017-12-27 13:46:21 -0500204 use quote::{ToTokens, Tokens};
David Tolnayf38cdf62016-09-23 19:07:09 -0700205
206 impl ToTokens for Variant {
207 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700208 tokens.append_all(&self.attrs);
David Tolnayf38cdf62016-09-23 19:07:09 -0700209 self.ident.to_tokens(tokens);
210 self.data.to_tokens(tokens);
David Tolnaye67902a2017-12-28 22:12:00 -0500211 if let Some((ref eq_token, ref disc)) = self.discriminant {
212 eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400213 disc.to_tokens(tokens);
214 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700215 }
216 }
217
218 impl ToTokens for VariantData {
219 fn to_tokens(&self, tokens: &mut Tokens) {
220 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700221 VariantData::Struct(ref fields, ref brace) => {
222 brace.surround(tokens, |tokens| {
223 fields.to_tokens(tokens);
224 });
David Tolnayf38cdf62016-09-23 19:07:09 -0700225 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700226 VariantData::Tuple(ref fields, ref paren) => {
227 paren.surround(tokens, |tokens| {
228 fields.to_tokens(tokens);
229 });
David Tolnayf38cdf62016-09-23 19:07:09 -0700230 }
231 VariantData::Unit => {}
232 }
233 }
234 }
235
236 impl ToTokens for Field {
237 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700238 tokens.append_all(&self.attrs);
David Tolnay47a877c2016-10-01 16:50:55 -0700239 self.vis.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400240 if let Some(ref ident) = self.ident {
241 ident.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -0700242 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400243 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700244 self.ty.to_tokens(tokens);
245 }
246 }
247
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700248 impl ToTokens for VisPublic {
David Tolnay47a877c2016-10-01 16:50:55 -0700249 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700250 self.pub_token.to_tokens(tokens)
251 }
252 }
Arnaviond32b2942017-04-29 17:18:02 -0700253
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700254 impl ToTokens for VisCrate {
255 fn to_tokens(&self, tokens: &mut Tokens) {
256 self.pub_token.to_tokens(tokens);
257 self.paren_token.surround(tokens, |tokens| {
258 self.crate_token.to_tokens(tokens);
259 })
260 }
261 }
Arnaviond32b2942017-04-29 17:18:02 -0700262
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700263 impl ToTokens for VisRestricted {
264 fn to_tokens(&self, tokens: &mut Tokens) {
265 self.pub_token.to_tokens(tokens);
266 self.paren_token.surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400267 // XXX: If we have a path which is not "self" or "super",
268 // automatically add the "in" token.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700269 self.in_token.to_tokens(tokens);
270 self.path.to_tokens(tokens);
271 });
272 }
273 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700274}