blob: 0f98116231e541b7515b64cc341897897b0f90a6 [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`
Michael Layzelld7ee9102017-06-07 10:02:19 -040017 pub discriminant: Option<Expr>,
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 Tolnayf38cdf62016-09-23 19:07:09 -0700110
Michael Layzell92639a52017-06-01 00:07:44 -0400111 use synom::Synom;
Alex Crichton954046c2017-05-30 21:49:42 -0700112 use synom::tokens;
113 use synom::tokens::*;
David Tolnayf38cdf62016-09-23 19:07:09 -0700114
Alex Crichton954046c2017-05-30 21:49:42 -0700115 impl Field {
Michael Layzell92639a52017-06-01 00:07:44 -0400116 named!(pub parse_struct -> Self, do_parse!(
117 attrs: many0!(call!(Attribute::parse_outer)) >>
118 vis: syn!(Visibility) >>
119 id: syn!(Ident) >>
120 colon: syn!(Colon) >>
121 ty: syn!(Ty) >>
122 (Field {
123 ident: Some(id),
124 vis: vis,
125 attrs: attrs,
126 ty: ty,
127 colon_token: Some(colon),
128 })
129 ));
David Tolnayf38cdf62016-09-23 19:07:09 -0700130
Michael Layzell92639a52017-06-01 00:07:44 -0400131 named!(pub parse_tuple -> Self, do_parse!(
132 attrs: many0!(call!(Attribute::parse_outer)) >>
133 vis: syn!(Visibility) >>
134 ty: syn!(Ty) >>
135 (Field {
136 ident: None,
137 colon_token: None,
138 vis: vis,
139 attrs: attrs,
140 ty: ty,
141 })
142 ));
Michael Layzell416724e2017-05-24 21:12:34 -0400143 }
144
Alex Crichton954046c2017-05-30 21:49:42 -0700145 impl Synom for Visibility {
Michael Layzell92639a52017-06-01 00:07:44 -0400146 named!(parse -> Self, alt!(
147 do_parse!(
148 pub_token: syn!(Pub) >>
149 other: parens!(syn!(tokens::Crate)) >>
150 (Visibility::Crate(VisCrate {
151 crate_token: other.0,
152 paren_token: other.1,
153 pub_token: pub_token,
154 }))
155 )
156 |
157 do_parse!(
158 pub_token: syn!(Pub) >>
159 other: parens!(syn!(Self_)) >>
160 (Visibility::Restricted(VisRestricted {
161 path: Box::new(other.0.into()),
162 in_token: None,
163 paren_token: other.1,
164 pub_token: pub_token,
165 }))
166 )
167 |
168 do_parse!(
169 pub_token: syn!(Pub) >>
170 other: parens!(syn!(Super)) >>
171 (Visibility::Restricted(VisRestricted {
172 path: Box::new(other.0.into()),
173 in_token: None,
174 paren_token: other.1,
175 pub_token: pub_token,
176 }))
177 )
178 |
179 do_parse!(
180 pub_token: syn!(Pub) >>
181 other: parens!(do_parse!(
182 in_tok: syn!(In) >>
183 restricted: call!(Path::parse_mod_style) >>
184 (in_tok, restricted)
185 )) >>
186 (Visibility::Restricted(VisRestricted {
187 path: Box::new((other.0).1),
188 in_token: Some((other.0).0),
189 paren_token: other.1,
190 pub_token: pub_token,
191 }))
192 )
193 |
194 syn!(Pub) => { |tok| {
195 Visibility::Public(VisPublic {
196 pub_token: tok,
197 })
198 } }
199 |
200 epsilon!() => { |_| Visibility::Inherited(VisInherited {}) }
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 Tolnayf38cdf62016-09-23 19:07:09 -0700208 use quote::{Tokens, ToTokens};
209
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);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400215 if let Some(ref disc) = self.discriminant {
Alex Crichton259ee532017-07-14 06:51:02 -0700216 TokensOrDefault(&self.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 {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700225 VariantData::Struct(ref fields, ref brace) => {
226 brace.surround(tokens, |tokens| {
227 fields.to_tokens(tokens);
228 });
David Tolnayf38cdf62016-09-23 19:07:09 -0700229 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700230 VariantData::Tuple(ref fields, ref paren) => {
231 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 }
Arnaviond32b2942017-04-29 17:18:02 -0700278
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700279 impl ToTokens for VisInherited {
280 fn to_tokens(&self, _tokens: &mut Tokens) {
David Tolnay47a877c2016-10-01 16:50:55 -0700281 }
282 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700283}