blob: f1e0c763993c98bb54f88845042302fb71ef3b1b [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
Alex Crichton62a0a592017-05-22 13:58:53 -070035ast_struct! {
36 /// A field of a struct or enum variant.
37 pub struct Field {
David Tolnay4a3f59a2017-12-28 21:21:12 -050038 /// Attributes tagged on the field.
39 pub attrs: Vec<Attribute>,
40
41 /// Visibility of the field.
42 pub vis: Visibility,
43
Alex Crichton62a0a592017-05-22 13:58:53 -070044 /// Name of the field, if any.
45 ///
46 /// Fields of tuple structs have no names.
47 pub ident: Option<Ident>,
Clar Charrd22b5702017-03-10 15:24:56 -050048
David Tolnay4a3f59a2017-12-28 21:21:12 -050049 pub colon_token: Option<Token![:]>,
Clar Charrd22b5702017-03-10 15:24:56 -050050
Alex Crichton62a0a592017-05-22 13:58:53 -070051 /// Type of the field.
David Tolnayfd6bf5c2017-11-12 09:41:14 -080052 pub ty: Type,
Alex Crichton62a0a592017-05-22 13:58:53 -070053 }
David Tolnayf38cdf62016-09-23 19:07:09 -070054}
55
Alex Crichtonccbb45d2017-05-23 10:58:24 -070056ast_enum_of_structs! {
Alex Crichton62a0a592017-05-22 13:58:53 -070057 /// Visibility level of an item.
58 pub enum Visibility {
59 /// Public, i.e. `pub`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -070060 pub Public(VisPublic {
David Tolnayf8db7ba2017-11-11 22:52:16 -080061 pub pub_token: Token![pub],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070062 }),
Clar Charrd22b5702017-03-10 15:24:56 -050063
Alex Crichton62a0a592017-05-22 13:58:53 -070064 /// Crate-visible, i.e. `pub(crate)`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -070065 pub Crate(VisCrate {
David Tolnayf8db7ba2017-11-11 22:52:16 -080066 pub pub_token: Token![pub],
David Tolnay32954ef2017-12-26 22:43:16 -050067 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -080068 pub crate_token: Token![crate],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070069 }),
Clar Charrd22b5702017-03-10 15:24:56 -050070
Alex Crichton62a0a592017-05-22 13:58:53 -070071 /// Restricted, e.g. `pub(self)` or `pub(super)` or `pub(in some::module)`.
Alex Crichtonccbb45d2017-05-23 10:58:24 -070072 pub Restricted(VisRestricted {
David Tolnayf8db7ba2017-11-11 22:52:16 -080073 pub pub_token: Token![pub],
David Tolnay32954ef2017-12-26 22:43:16 -050074 pub paren_token: token::Paren,
David Tolnayf8db7ba2017-11-11 22:52:16 -080075 pub in_token: Option<Token![in]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070076 pub path: Box<Path>,
77 }),
Clar Charrd22b5702017-03-10 15:24:56 -050078
Alex Crichton62a0a592017-05-22 13:58:53 -070079 /// Inherited, i.e. private.
David Tolnayfcfb9002017-12-28 22:04:29 -050080 pub Inherited,
Alex Crichton62a0a592017-05-22 13:58:53 -070081 }
David Tolnayf38cdf62016-09-23 19:07:09 -070082}
83
David Tolnayf38cdf62016-09-23 19:07:09 -070084#[cfg(feature = "parsing")]
85pub mod parsing {
86 use super::*;
David Tolnayf38cdf62016-09-23 19:07:09 -070087
Michael Layzell92639a52017-06-01 00:07:44 -040088 use synom::Synom;
David Tolnayf38cdf62016-09-23 19:07:09 -070089
Alex Crichton954046c2017-05-30 21:49:42 -070090 impl Field {
Michael Layzell92639a52017-06-01 00:07:44 -040091 named!(pub parse_struct -> Self, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -050092 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell92639a52017-06-01 00:07:44 -040093 vis: syn!(Visibility) >>
94 id: syn!(Ident) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -080095 colon: punct!(:) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -080096 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -040097 (Field {
98 ident: Some(id),
99 vis: vis,
100 attrs: attrs,
101 ty: ty,
102 colon_token: Some(colon),
103 })
104 ));
David Tolnayf38cdf62016-09-23 19:07:09 -0700105
Michael Layzell92639a52017-06-01 00:07:44 -0400106 named!(pub parse_tuple -> Self, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -0500107 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400108 vis: syn!(Visibility) >>
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800109 ty: syn!(Type) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400110 (Field {
111 ident: None,
112 colon_token: None,
113 vis: vis,
114 attrs: attrs,
115 ty: ty,
116 })
117 ));
Michael Layzell416724e2017-05-24 21:12:34 -0400118 }
119
Alex Crichton954046c2017-05-30 21:49:42 -0700120 impl Synom for Visibility {
Michael Layzell92639a52017-06-01 00:07:44 -0400121 named!(parse -> Self, alt!(
122 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800123 pub_token: keyword!(pub) >>
124 other: parens!(keyword!(crate)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400125 (Visibility::Crate(VisCrate {
Michael Layzell92639a52017-06-01 00:07:44 -0400126 pub_token: pub_token,
David Tolnay8875fca2017-12-31 13:52:37 -0500127 paren_token: other.0,
128 crate_token: other.1,
Michael Layzell92639a52017-06-01 00:07:44 -0400129 }))
130 )
131 |
132 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800133 pub_token: keyword!(pub) >>
134 other: parens!(keyword!(self)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400135 (Visibility::Restricted(VisRestricted {
Michael Layzell92639a52017-06-01 00:07:44 -0400136 pub_token: pub_token,
David Tolnay8875fca2017-12-31 13:52:37 -0500137 paren_token: other.0,
138 in_token: None,
139 path: Box::new(other.1.into()),
Michael Layzell92639a52017-06-01 00:07:44 -0400140 }))
141 )
142 |
143 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800144 pub_token: keyword!(pub) >>
145 other: parens!(keyword!(super)) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400146 (Visibility::Restricted(VisRestricted {
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 in_token: None,
150 path: Box::new(other.1.into()),
Michael Layzell92639a52017-06-01 00:07:44 -0400151 }))
152 )
153 |
154 do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800155 pub_token: keyword!(pub) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400156 other: parens!(do_parse!(
David Tolnayf8db7ba2017-11-11 22:52:16 -0800157 in_tok: keyword!(in) >>
Michael Layzell92639a52017-06-01 00:07:44 -0400158 restricted: call!(Path::parse_mod_style) >>
159 (in_tok, restricted)
160 )) >>
161 (Visibility::Restricted(VisRestricted {
Michael Layzell92639a52017-06-01 00:07:44 -0400162 pub_token: pub_token,
David Tolnay8875fca2017-12-31 13:52:37 -0500163 paren_token: other.0,
164 in_token: Some((other.1).0),
165 path: Box::new((other.1).1),
Michael Layzell92639a52017-06-01 00:07:44 -0400166 }))
167 )
168 |
David Tolnayf8db7ba2017-11-11 22:52:16 -0800169 keyword!(pub) => { |tok| {
Michael Layzell92639a52017-06-01 00:07:44 -0400170 Visibility::Public(VisPublic {
171 pub_token: tok,
172 })
173 } }
174 |
David Tolnayfcfb9002017-12-28 22:04:29 -0500175 epsilon!() => { |_| Visibility::Inherited }
Michael Layzell92639a52017-06-01 00:07:44 -0400176 ));
Sergio Benitez5680d6a2017-12-29 11:20:29 -0800177
178 fn description() -> Option<&'static str> {
179 Some("visibility qualifier, e.g. `pub`")
180 }
Alex Crichton954046c2017-05-30 21:49:42 -0700181 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700182}
183
184#[cfg(feature = "printing")]
185mod printing {
186 use super::*;
David Tolnay51382052017-12-27 13:46:21 -0500187 use quote::{ToTokens, Tokens};
David Tolnayf38cdf62016-09-23 19:07:09 -0700188
189 impl ToTokens for Variant {
190 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700191 tokens.append_all(&self.attrs);
David Tolnayf38cdf62016-09-23 19:07:09 -0700192 self.ident.to_tokens(tokens);
193 self.data.to_tokens(tokens);
David Tolnaye67902a2017-12-28 22:12:00 -0500194 if let Some((ref eq_token, ref disc)) = self.discriminant {
195 eq_token.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400196 disc.to_tokens(tokens);
197 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700198 }
199 }
200
201 impl ToTokens for VariantData {
202 fn to_tokens(&self, tokens: &mut Tokens) {
203 match *self {
David Tolnay8875fca2017-12-31 13:52:37 -0500204 VariantData::Struct(ref brace, ref fields) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700205 brace.surround(tokens, |tokens| {
206 fields.to_tokens(tokens);
207 });
David Tolnayf38cdf62016-09-23 19:07:09 -0700208 }
David Tolnay8875fca2017-12-31 13:52:37 -0500209 VariantData::Tuple(ref paren, ref fields) => {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700210 paren.surround(tokens, |tokens| {
211 fields.to_tokens(tokens);
212 });
David Tolnayf38cdf62016-09-23 19:07:09 -0700213 }
214 VariantData::Unit => {}
215 }
216 }
217 }
218
219 impl ToTokens for Field {
220 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700221 tokens.append_all(&self.attrs);
David Tolnay47a877c2016-10-01 16:50:55 -0700222 self.vis.to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400223 if let Some(ref ident) = self.ident {
224 ident.to_tokens(tokens);
Alex Crichton259ee532017-07-14 06:51:02 -0700225 TokensOrDefault(&self.colon_token).to_tokens(tokens);
Michael Layzell3936ceb2017-07-08 00:28:36 -0400226 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700227 self.ty.to_tokens(tokens);
228 }
229 }
230
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700231 impl ToTokens for VisPublic {
David Tolnay47a877c2016-10-01 16:50:55 -0700232 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700233 self.pub_token.to_tokens(tokens)
234 }
235 }
Arnaviond32b2942017-04-29 17:18:02 -0700236
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700237 impl ToTokens for VisCrate {
238 fn to_tokens(&self, tokens: &mut Tokens) {
239 self.pub_token.to_tokens(tokens);
240 self.paren_token.surround(tokens, |tokens| {
241 self.crate_token.to_tokens(tokens);
242 })
243 }
244 }
Arnaviond32b2942017-04-29 17:18:02 -0700245
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700246 impl ToTokens for VisRestricted {
247 fn to_tokens(&self, tokens: &mut Tokens) {
248 self.pub_token.to_tokens(tokens);
249 self.paren_token.surround(tokens, |tokens| {
Michael Layzell3936ceb2017-07-08 00:28:36 -0400250 // XXX: If we have a path which is not "self" or "super",
251 // automatically add the "in" token.
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700252 self.in_token.to_tokens(tokens);
253 self.path.to_tokens(tokens);
254 });
255 }
256 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700257}