blob: 290c8ff6a38325a8c8486e518d13faf9e57388fc [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 Tolnayf38cdf62016-09-23 19:07:09 -0700110
Alex Crichton954046c2017-05-30 21:49:42 -0700111 use synom::{IResult, Synom};
112 use synom::tokens;
113 use synom::tokens::*;
114 use proc_macro2::TokenTree;
David Tolnayf38cdf62016-09-23 19:07:09 -0700115
Alex Crichton954046c2017-05-30 21:49:42 -0700116 impl Field {
117 pub fn parse_struct(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
118 do_parse! {
119 input,
120 attrs: many0!(call!(Attribute::parse_outer)) >>
121 vis: syn!(Visibility) >>
122 id: syn!(Ident) >>
123 colon: syn!(Colon) >>
124 ty: syn!(Ty) >>
125 (Field {
126 ident: Some(id),
127 vis: vis,
128 attrs: attrs,
129 ty: ty,
130 colon_token: Some(colon),
131 })
132 }
133 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700134
Alex Crichton954046c2017-05-30 21:49:42 -0700135 pub fn parse_tuple(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
136 do_parse! {
137 input,
138 attrs: many0!(call!(Attribute::parse_outer)) >>
139 vis: syn!(Visibility) >>
140 ty: syn!(Ty) >>
141 (Field {
142 ident: None,
143 colon_token: None,
144 vis: vis,
145 attrs: attrs,
146 ty: ty,
147 })
148 }
Michael Layzell416724e2017-05-24 21:12:34 -0400149 }
150 }
151
Alex Crichton954046c2017-05-30 21:49:42 -0700152 impl Synom for Visibility {
153 fn parse(input: &[TokenTree]) -> IResult<&[TokenTree], Self> {
154 alt! {
155 input,
156 do_parse!(
157 pub_token: syn!(Pub) >>
158 other: parens!(syn!(tokens::Crate)) >>
159 (Visibility::Crate(VisCrate {
160 crate_token: other.0,
161 paren_token: other.1,
162 pub_token: pub_token,
163 }))
164 )
165 |
166 do_parse!(
167 pub_token: syn!(Pub) >>
168 other: parens!(syn!(Self_)) >>
169 (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!(
178 pub_token: syn!(Pub) >>
179 other: parens!(syn!(Super)) >>
180 (Visibility::Restricted(VisRestricted {
181 path: Box::new(other.0.into()),
182 in_token: None,
183 paren_token: other.1,
184 pub_token: pub_token,
185 }))
186 )
187 |
188 do_parse!(
189 pub_token: syn!(Pub) >>
190 other: parens!(do_parse!(
191 in_tok: syn!(In) >>
192 restricted: call!(Path::parse_mod_style) >>
193 (in_tok, restricted)
194 )) >>
195 (Visibility::Restricted(VisRestricted {
196 path: Box::new((other.0).1),
197 in_token: Some((other.0).0),
198 paren_token: other.1,
199 pub_token: pub_token,
200 }))
201 )
202 |
203 syn!(Pub) => { |tok| {
204 Visibility::Public(VisPublic {
205 pub_token: tok,
206 })
207 } }
208 |
209 epsilon!() => { |_| Visibility::Inherited(VisInherited {}) }
210 }
211 }
212 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700213}
214
215#[cfg(feature = "printing")]
216mod printing {
217 use super::*;
David Tolnayf38cdf62016-09-23 19:07:09 -0700218 use quote::{Tokens, ToTokens};
219
220 impl ToTokens for Variant {
221 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700222 tokens.append_all(&self.attrs);
David Tolnayf38cdf62016-09-23 19:07:09 -0700223 self.ident.to_tokens(tokens);
224 self.data.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700225 self.eq_token.to_tokens(tokens);
226 self.discriminant.to_tokens(tokens);
David Tolnayf38cdf62016-09-23 19:07:09 -0700227 }
228 }
229
230 impl ToTokens for VariantData {
231 fn to_tokens(&self, tokens: &mut Tokens) {
232 match *self {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700233 VariantData::Struct(ref fields, ref brace) => {
234 brace.surround(tokens, |tokens| {
235 fields.to_tokens(tokens);
236 });
David Tolnayf38cdf62016-09-23 19:07:09 -0700237 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700238 VariantData::Tuple(ref fields, ref paren) => {
239 paren.surround(tokens, |tokens| {
240 fields.to_tokens(tokens);
241 });
David Tolnayf38cdf62016-09-23 19:07:09 -0700242 }
243 VariantData::Unit => {}
244 }
245 }
246 }
247
248 impl ToTokens for Field {
249 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700250 tokens.append_all(&self.attrs);
David Tolnay47a877c2016-10-01 16:50:55 -0700251 self.vis.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700252 self.ident.to_tokens(tokens);
253 self.colon_token.to_tokens(tokens);
David Tolnayf38cdf62016-09-23 19:07:09 -0700254 self.ty.to_tokens(tokens);
255 }
256 }
257
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700258 impl ToTokens for VisPublic {
David Tolnay47a877c2016-10-01 16:50:55 -0700259 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700260 self.pub_token.to_tokens(tokens)
261 }
262 }
Arnaviond32b2942017-04-29 17:18:02 -0700263
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700264 impl ToTokens for VisCrate {
265 fn to_tokens(&self, tokens: &mut Tokens) {
266 self.pub_token.to_tokens(tokens);
267 self.paren_token.surround(tokens, |tokens| {
268 self.crate_token.to_tokens(tokens);
269 })
270 }
271 }
Arnaviond32b2942017-04-29 17:18:02 -0700272
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700273 impl ToTokens for VisRestricted {
274 fn to_tokens(&self, tokens: &mut Tokens) {
275 self.pub_token.to_tokens(tokens);
276 self.paren_token.surround(tokens, |tokens| {
277 self.in_token.to_tokens(tokens);
278 self.path.to_tokens(tokens);
279 });
280 }
281 }
Arnaviond32b2942017-04-29 17:18:02 -0700282
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700283 impl ToTokens for VisInherited {
284 fn to_tokens(&self, _tokens: &mut Tokens) {
David Tolnay47a877c2016-10-01 16:50:55 -0700285 }
286 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700287}