blob: 69df303b093ae4f34126de1420b6a5e95b6ae73d [file] [log] [blame]
David Tolnayf38cdf62016-09-23 19:07:09 -07001use super::*;
2
Clar Charrd22b5702017-03-10 15:24:56 -05003/// An enum variant.
David Tolnay9bf4af82017-01-07 11:17:46 -08004#[derive(Debug, Clone, Eq, PartialEq, Hash)]
David Tolnayf38cdf62016-09-23 19:07:09 -07005pub struct Variant {
Clar Charrd22b5702017-03-10 15:24:56 -05006 /// Name of the variant.
David Tolnayf38cdf62016-09-23 19:07:09 -07007 pub ident: Ident,
Clar Charrd22b5702017-03-10 15:24:56 -05008
9 /// Attributes tagged on the variant.
David Tolnayf38cdf62016-09-23 19:07:09 -070010 pub attrs: Vec<Attribute>,
Clar Charrd22b5702017-03-10 15:24:56 -050011
12 /// Type of variant.
David Tolnayf38cdf62016-09-23 19:07:09 -070013 pub data: VariantData,
Clar Charrd22b5702017-03-10 15:24:56 -050014
David Tolnayf38cdf62016-09-23 19:07:09 -070015 /// Explicit discriminant, e.g. `Foo = 1`
David Tolnay3cb23a92016-10-07 23:02:21 -070016 pub discriminant: Option<ConstExpr>,
David Tolnayf38cdf62016-09-23 19:07:09 -070017}
18
Clar Charrd22b5702017-03-10 15:24:56 -050019/// Data stored within an enum variant or struct.
David Tolnay9bf4af82017-01-07 11:17:46 -080020#[derive(Debug, Clone, Eq, PartialEq, Hash)]
David Tolnayf38cdf62016-09-23 19:07:09 -070021pub enum VariantData {
Clar Charrd22b5702017-03-10 15:24:56 -050022 /// Struct variant, e.g. `Point { x: f64, y: f64 }`.
David Tolnayf38cdf62016-09-23 19:07:09 -070023 Struct(Vec<Field>),
Clar Charrd22b5702017-03-10 15:24:56 -050024
25 /// Tuple variant, e.g. `Some(T)`.
David Tolnayf38cdf62016-09-23 19:07:09 -070026 Tuple(Vec<Field>),
Clar Charrd22b5702017-03-10 15:24:56 -050027
28 /// Unit variant, e.g. `None`.
David Tolnayf38cdf62016-09-23 19:07:09 -070029 Unit,
30}
31
32impl VariantData {
Clar Charrd22b5702017-03-10 15:24:56 -050033 /// Slice containing the fields stored in the variant.
David Tolnayf38cdf62016-09-23 19:07:09 -070034 pub fn fields(&self) -> &[Field] {
35 match *self {
36 VariantData::Struct(ref fields) |
37 VariantData::Tuple(ref fields) => fields,
38 VariantData::Unit => &[],
39 }
40 }
Sean Griffin15085c42016-10-03 11:40:31 -040041
Clar Charrd22b5702017-03-10 15:24:56 -050042 /// Mutable slice containing the fields stored in the variant.
Sean Griffin15085c42016-10-03 11:40:31 -040043 pub fn fields_mut(&mut self) -> &mut [Field] {
44 match *self {
45 VariantData::Struct(ref mut fields) |
46 VariantData::Tuple(ref mut fields) => fields,
47 VariantData::Unit => &mut [],
48 }
49 }
David Tolnayf38cdf62016-09-23 19:07:09 -070050}
51
Clar Charrd22b5702017-03-10 15:24:56 -050052/// A field of a struct or enum variant.
David Tolnay9bf4af82017-01-07 11:17:46 -080053#[derive(Debug, Clone, Eq, PartialEq, Hash)]
David Tolnayf38cdf62016-09-23 19:07:09 -070054pub struct Field {
Clar Charrd22b5702017-03-10 15:24:56 -050055 /// Name of the field, if any.
56 ///
57 /// Fields of tuple structs have no names.
David Tolnayf38cdf62016-09-23 19:07:09 -070058 pub ident: Option<Ident>,
Clar Charrd22b5702017-03-10 15:24:56 -050059
60 /// Visibility of the field.
David Tolnayf38cdf62016-09-23 19:07:09 -070061 pub vis: Visibility,
Clar Charrd22b5702017-03-10 15:24:56 -050062
63 /// Attributes tagged on the field.
David Tolnayf38cdf62016-09-23 19:07:09 -070064 pub attrs: Vec<Attribute>,
Clar Charrd22b5702017-03-10 15:24:56 -050065
66 /// Type of the field.
David Tolnayf38cdf62016-09-23 19:07:09 -070067 pub ty: Ty,
68}
69
Clar Charrd22b5702017-03-10 15:24:56 -050070
71/// Visibility level of an item.
David Tolnay9bf4af82017-01-07 11:17:46 -080072#[derive(Debug, Clone, Eq, PartialEq, Hash)]
David Tolnayf38cdf62016-09-23 19:07:09 -070073pub enum Visibility {
Clar Charrd22b5702017-03-10 15:24:56 -050074 /// Public, i.e. `pub`.
David Tolnayf38cdf62016-09-23 19:07:09 -070075 Public,
Clar Charrd22b5702017-03-10 15:24:56 -050076
77 /// Crate-visible, i.e. `pub(crate)`.
David Tolnaye07f9e02016-10-30 17:05:55 -070078 Crate,
Clar Charrd22b5702017-03-10 15:24:56 -050079
Arnaviond32b2942017-04-29 17:18:02 -070080 /// Restricted, e.g. `pub(self)` or `pub(super)` or `pub(in some::module)`.
David Tolnaye07f9e02016-10-30 17:05:55 -070081 Restricted(Box<Path>),
Clar Charrd22b5702017-03-10 15:24:56 -050082
83 /// Inherited, i.e. private.
David Tolnayf38cdf62016-09-23 19:07:09 -070084 Inherited,
85}
86
David Tolnayf38cdf62016-09-23 19:07:09 -070087#[cfg(feature = "parsing")]
88pub mod parsing {
89 use super::*;
David Tolnay28c1db62016-10-27 22:48:18 -070090 use WhereClause;
David Tolnay514f1292017-02-27 12:30:57 -080091 #[cfg(feature = "full")]
92 use ConstExpr;
David Tolnay4a51dc72016-10-01 00:40:31 -070093 use attr::parsing::outer_attr;
David Tolnayf945fb52017-02-27 12:53:54 -080094 #[cfg(feature = "full")]
David Tolnay3cb23a92016-10-07 23:02:21 -070095 use constant::parsing::const_expr;
David Tolnay514f1292017-02-27 12:30:57 -080096 #[cfg(feature = "full")]
97 use expr::parsing::expr;
David Tolnay28c1db62016-10-27 22:48:18 -070098 use generics::parsing::where_clause;
David Tolnayf38cdf62016-09-23 19:07:09 -070099 use ident::parsing::ident;
Arnaviond32b2942017-04-29 17:18:02 -0700100 use ty::parsing::{mod_style_path, ty};
David Tolnayf38cdf62016-09-23 19:07:09 -0700101
David Tolnay28c1db62016-10-27 22:48:18 -0700102 named!(pub struct_body -> (WhereClause, VariantData), alt!(
103 do_parse!(
104 wh: where_clause >>
105 body: struct_like_body >>
106 (wh, VariantData::Struct(body))
107 )
David Tolnayf38cdf62016-09-23 19:07:09 -0700108 |
David Tolnay28c1db62016-10-27 22:48:18 -0700109 do_parse!(
110 body: tuple_like_body >>
111 wh: where_clause >>
112 punct!(";") >>
113 (wh, VariantData::Tuple(body))
114 )
David Tolnayf38cdf62016-09-23 19:07:09 -0700115 |
David Tolnay28c1db62016-10-27 22:48:18 -0700116 do_parse!(
117 wh: where_clause >>
118 punct!(";") >>
119 (wh, VariantData::Unit)
120 )
David Tolnayf38cdf62016-09-23 19:07:09 -0700121 ));
122
David Tolnay28c1db62016-10-27 22:48:18 -0700123 named!(pub enum_body -> (WhereClause, Vec<Variant>), do_parse!(
124 wh: where_clause >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700125 punct!("{") >>
David Tolnayff46fd22016-10-08 13:53:28 -0700126 variants: terminated_list!(punct!(","), variant) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700127 punct!("}") >>
David Tolnay28c1db62016-10-27 22:48:18 -0700128 (wh, variants)
David Tolnayf38cdf62016-09-23 19:07:09 -0700129 ));
130
131 named!(variant -> Variant, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700132 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700133 id: ident >>
134 data: alt!(
135 struct_like_body => { VariantData::Struct }
136 |
137 tuple_like_body => { VariantData::Tuple }
138 |
139 epsilon!() => { |_| VariantData::Unit }
140 ) >>
David Tolnay514f1292017-02-27 12:30:57 -0800141 disr: option!(preceded!(punct!("="), discriminant)) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700142 (Variant {
143 ident: id,
144 attrs: attrs,
145 data: data,
146 discriminant: disr,
147 })
148 ));
149
David Tolnay514f1292017-02-27 12:30:57 -0800150 #[cfg(not(feature = "full"))]
David Tolnayf945fb52017-02-27 12:53:54 -0800151 use constant::parsing::const_expr as discriminant;
David Tolnay514f1292017-02-27 12:30:57 -0800152
153 #[cfg(feature = "full")]
154 named!(discriminant -> ConstExpr, alt!(
155 terminated!(const_expr, after_discriminant)
156 |
157 terminated!(expr, after_discriminant) => { ConstExpr::Other }
158 ));
159
160 #[cfg(feature = "full")]
161 named!(after_discriminant -> &str, peek!(alt!(punct!(",") | punct!("}"))));
162
David Tolnay2f9fa632016-10-03 22:08:48 -0700163 named!(pub struct_like_body -> Vec<Field>, do_parse!(
David Tolnayf38cdf62016-09-23 19:07:09 -0700164 punct!("{") >>
David Tolnayff46fd22016-10-08 13:53:28 -0700165 fields: terminated_list!(punct!(","), struct_field) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700166 punct!("}") >>
167 (fields)
168 ));
169
170 named!(tuple_like_body -> Vec<Field>, do_parse!(
171 punct!("(") >>
David Tolnayff46fd22016-10-08 13:53:28 -0700172 fields: terminated_list!(punct!(","), tuple_field) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700173 punct!(")") >>
174 (fields)
175 ));
176
177 named!(struct_field -> Field, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700178 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700179 vis: visibility >>
180 id: ident >>
181 punct!(":") >>
182 ty: ty >>
183 (Field {
184 ident: Some(id),
185 vis: vis,
186 attrs: attrs,
187 ty: ty,
188 })
189 ));
190
191 named!(tuple_field -> Field, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700192 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700193 vis: visibility >>
194 ty: ty >>
195 (Field {
196 ident: None,
197 vis: vis,
198 attrs: attrs,
199 ty: ty,
200 })
201 ));
202
203 named!(pub visibility -> Visibility, alt!(
David Tolnaye07f9e02016-10-30 17:05:55 -0700204 do_parse!(
205 keyword!("pub") >>
206 punct!("(") >>
207 keyword!("crate") >>
208 punct!(")") >>
209 (Visibility::Crate)
210 )
211 |
212 do_parse!(
213 keyword!("pub") >>
214 punct!("(") >>
Arnaviond32b2942017-04-29 17:18:02 -0700215 keyword!("self") >>
216 punct!(")") >>
217 (Visibility::Restricted(Box::new("self".into())))
218 )
219 |
220 do_parse!(
221 keyword!("pub") >>
222 punct!("(") >>
223 keyword!("super") >>
224 punct!(")") >>
225 (Visibility::Restricted(Box::new("super".into())))
226 )
227 |
228 do_parse!(
229 keyword!("pub") >>
230 punct!("(") >>
231 keyword!("in") >>
232 restricted: mod_style_path >>
David Tolnaye07f9e02016-10-30 17:05:55 -0700233 punct!(")") >>
234 (Visibility::Restricted(Box::new(restricted)))
235 )
236 |
David Tolnaybd76e572016-10-02 13:43:16 -0700237 keyword!("pub") => { |_| Visibility::Public }
David Tolnayf38cdf62016-09-23 19:07:09 -0700238 |
239 epsilon!() => { |_| Visibility::Inherited }
240 ));
David Tolnayf38cdf62016-09-23 19:07:09 -0700241}
242
243#[cfg(feature = "printing")]
244mod printing {
245 use super::*;
David Tolnayf38cdf62016-09-23 19:07:09 -0700246 use quote::{Tokens, ToTokens};
Arnaviond32b2942017-04-29 17:18:02 -0700247 use ty::PathParameters;
David Tolnayf38cdf62016-09-23 19:07:09 -0700248
249 impl ToTokens for Variant {
250 fn to_tokens(&self, tokens: &mut Tokens) {
251 for attr in &self.attrs {
252 attr.to_tokens(tokens);
253 }
254 self.ident.to_tokens(tokens);
255 self.data.to_tokens(tokens);
256 if let Some(ref disr) = self.discriminant {
257 tokens.append("=");
258 disr.to_tokens(tokens);
259 }
260 }
261 }
262
263 impl ToTokens for VariantData {
264 fn to_tokens(&self, tokens: &mut Tokens) {
265 match *self {
266 VariantData::Struct(ref fields) => {
267 tokens.append("{");
268 tokens.append_separated(fields, ",");
269 tokens.append("}");
270 }
271 VariantData::Tuple(ref fields) => {
272 tokens.append("(");
273 tokens.append_separated(fields, ",");
274 tokens.append(")");
275 }
276 VariantData::Unit => {}
277 }
278 }
279 }
280
281 impl ToTokens for Field {
282 fn to_tokens(&self, tokens: &mut Tokens) {
283 for attr in &self.attrs {
284 attr.to_tokens(tokens);
285 }
David Tolnay47a877c2016-10-01 16:50:55 -0700286 self.vis.to_tokens(tokens);
David Tolnayf38cdf62016-09-23 19:07:09 -0700287 if let Some(ref ident) = self.ident {
288 ident.to_tokens(tokens);
289 tokens.append(":");
290 }
291 self.ty.to_tokens(tokens);
292 }
293 }
294
David Tolnay47a877c2016-10-01 16:50:55 -0700295 impl ToTokens for Visibility {
296 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaye07f9e02016-10-30 17:05:55 -0700297 match *self {
298 Visibility::Public => tokens.append("pub"),
299 Visibility::Crate => {
300 tokens.append("pub");
301 tokens.append("(");
302 tokens.append("crate");
303 tokens.append(")");
304 }
305 Visibility::Restricted(ref path) => {
306 tokens.append("pub");
307 tokens.append("(");
Arnaviond32b2942017-04-29 17:18:02 -0700308
309 if !path.global &&
310 path.segments.len() == 1 &&
311 (path.segments[0].ident == "self" || path.segments[0].ident == "super") &&
312 path.segments[0].parameters == PathParameters::none() {
313
314 // Don't emit preceding `in` if path is `self` or `super`
315 } else {
316 tokens.append("in");
317 }
318
David Tolnaye07f9e02016-10-30 17:05:55 -0700319 path.to_tokens(tokens);
320 tokens.append(")");
321 }
322 Visibility::Inherited => {}
David Tolnay47a877c2016-10-01 16:50:55 -0700323 }
324 }
325 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700326}