blob: 3b90b1fc6b2f03b0d4759ab9d0bdd622feb418a6 [file] [log] [blame]
David Tolnayf38cdf62016-09-23 19:07:09 -07001use super::*;
2
David Tolnay9bf4af82017-01-07 11:17:46 -08003#[derive(Debug, Clone, Eq, PartialEq, Hash)]
David Tolnayf38cdf62016-09-23 19:07:09 -07004pub struct Variant {
5 pub ident: Ident,
6 pub attrs: Vec<Attribute>,
7 pub data: VariantData,
8 /// Explicit discriminant, e.g. `Foo = 1`
David Tolnay3cb23a92016-10-07 23:02:21 -07009 pub discriminant: Option<ConstExpr>,
David Tolnayf38cdf62016-09-23 19:07:09 -070010}
11
David Tolnay9bf4af82017-01-07 11:17:46 -080012#[derive(Debug, Clone, Eq, PartialEq, Hash)]
David Tolnayf38cdf62016-09-23 19:07:09 -070013pub enum VariantData {
14 Struct(Vec<Field>),
15 Tuple(Vec<Field>),
16 Unit,
17}
18
19impl VariantData {
20 pub fn fields(&self) -> &[Field] {
21 match *self {
22 VariantData::Struct(ref fields) |
23 VariantData::Tuple(ref fields) => fields,
24 VariantData::Unit => &[],
25 }
26 }
Sean Griffin15085c42016-10-03 11:40:31 -040027
28 pub fn fields_mut(&mut self) -> &mut [Field] {
29 match *self {
30 VariantData::Struct(ref mut fields) |
31 VariantData::Tuple(ref mut fields) => fields,
32 VariantData::Unit => &mut [],
33 }
34 }
David Tolnayf38cdf62016-09-23 19:07:09 -070035}
36
David Tolnay9bf4af82017-01-07 11:17:46 -080037#[derive(Debug, Clone, Eq, PartialEq, Hash)]
David Tolnayf38cdf62016-09-23 19:07:09 -070038pub struct Field {
39 pub ident: Option<Ident>,
40 pub vis: Visibility,
41 pub attrs: Vec<Attribute>,
42 pub ty: Ty,
43}
44
David Tolnay9bf4af82017-01-07 11:17:46 -080045#[derive(Debug, Clone, Eq, PartialEq, Hash)]
David Tolnayf38cdf62016-09-23 19:07:09 -070046pub enum Visibility {
47 Public,
David Tolnaye07f9e02016-10-30 17:05:55 -070048 Crate,
49 Restricted(Box<Path>),
David Tolnayf38cdf62016-09-23 19:07:09 -070050 Inherited,
51}
52
David Tolnayf38cdf62016-09-23 19:07:09 -070053#[cfg(feature = "parsing")]
54pub mod parsing {
55 use super::*;
David Tolnay28c1db62016-10-27 22:48:18 -070056 use WhereClause;
David Tolnay514f1292017-02-27 12:30:57 -080057 #[cfg(feature = "full")]
58 use ConstExpr;
David Tolnay4a51dc72016-10-01 00:40:31 -070059 use attr::parsing::outer_attr;
David Tolnay3cb23a92016-10-07 23:02:21 -070060 use constant::parsing::const_expr;
David Tolnay514f1292017-02-27 12:30:57 -080061 #[cfg(feature = "full")]
62 use expr::parsing::expr;
David Tolnay28c1db62016-10-27 22:48:18 -070063 use generics::parsing::where_clause;
David Tolnayf38cdf62016-09-23 19:07:09 -070064 use ident::parsing::ident;
David Tolnaye07f9e02016-10-30 17:05:55 -070065 use ty::parsing::{path, ty};
David Tolnayf38cdf62016-09-23 19:07:09 -070066
David Tolnay28c1db62016-10-27 22:48:18 -070067 named!(pub struct_body -> (WhereClause, VariantData), alt!(
68 do_parse!(
69 wh: where_clause >>
70 body: struct_like_body >>
71 (wh, VariantData::Struct(body))
72 )
David Tolnayf38cdf62016-09-23 19:07:09 -070073 |
David Tolnay28c1db62016-10-27 22:48:18 -070074 do_parse!(
75 body: tuple_like_body >>
76 wh: where_clause >>
77 punct!(";") >>
78 (wh, VariantData::Tuple(body))
79 )
David Tolnayf38cdf62016-09-23 19:07:09 -070080 |
David Tolnay28c1db62016-10-27 22:48:18 -070081 do_parse!(
82 wh: where_clause >>
83 punct!(";") >>
84 (wh, VariantData::Unit)
85 )
David Tolnayf38cdf62016-09-23 19:07:09 -070086 ));
87
David Tolnay28c1db62016-10-27 22:48:18 -070088 named!(pub enum_body -> (WhereClause, Vec<Variant>), do_parse!(
89 wh: where_clause >>
David Tolnayf38cdf62016-09-23 19:07:09 -070090 punct!("{") >>
David Tolnayff46fd22016-10-08 13:53:28 -070091 variants: terminated_list!(punct!(","), variant) >>
David Tolnayf38cdf62016-09-23 19:07:09 -070092 punct!("}") >>
David Tolnay28c1db62016-10-27 22:48:18 -070093 (wh, variants)
David Tolnayf38cdf62016-09-23 19:07:09 -070094 ));
95
96 named!(variant -> Variant, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -070097 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -070098 id: ident >>
99 data: alt!(
100 struct_like_body => { VariantData::Struct }
101 |
102 tuple_like_body => { VariantData::Tuple }
103 |
104 epsilon!() => { |_| VariantData::Unit }
105 ) >>
David Tolnay514f1292017-02-27 12:30:57 -0800106 disr: option!(preceded!(punct!("="), discriminant)) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700107 (Variant {
108 ident: id,
109 attrs: attrs,
110 data: data,
111 discriminant: disr,
112 })
113 ));
114
David Tolnay514f1292017-02-27 12:30:57 -0800115 #[cfg(not(feature = "full"))]
116 use self::const_expr as discriminant;
117
118 #[cfg(feature = "full")]
119 named!(discriminant -> ConstExpr, alt!(
120 terminated!(const_expr, after_discriminant)
121 |
122 terminated!(expr, after_discriminant) => { ConstExpr::Other }
123 ));
124
125 #[cfg(feature = "full")]
126 named!(after_discriminant -> &str, peek!(alt!(punct!(",") | punct!("}"))));
127
David Tolnay2f9fa632016-10-03 22:08:48 -0700128 named!(pub struct_like_body -> Vec<Field>, do_parse!(
David Tolnayf38cdf62016-09-23 19:07:09 -0700129 punct!("{") >>
David Tolnayff46fd22016-10-08 13:53:28 -0700130 fields: terminated_list!(punct!(","), struct_field) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700131 punct!("}") >>
132 (fields)
133 ));
134
135 named!(tuple_like_body -> Vec<Field>, do_parse!(
136 punct!("(") >>
David Tolnayff46fd22016-10-08 13:53:28 -0700137 fields: terminated_list!(punct!(","), tuple_field) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700138 punct!(")") >>
139 (fields)
140 ));
141
142 named!(struct_field -> Field, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700143 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700144 vis: visibility >>
145 id: ident >>
146 punct!(":") >>
147 ty: ty >>
148 (Field {
149 ident: Some(id),
150 vis: vis,
151 attrs: attrs,
152 ty: ty,
153 })
154 ));
155
156 named!(tuple_field -> Field, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700157 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700158 vis: visibility >>
159 ty: ty >>
160 (Field {
161 ident: None,
162 vis: vis,
163 attrs: attrs,
164 ty: ty,
165 })
166 ));
167
168 named!(pub visibility -> Visibility, alt!(
David Tolnaye07f9e02016-10-30 17:05:55 -0700169 do_parse!(
170 keyword!("pub") >>
171 punct!("(") >>
172 keyword!("crate") >>
173 punct!(")") >>
174 (Visibility::Crate)
175 )
176 |
177 do_parse!(
178 keyword!("pub") >>
179 punct!("(") >>
180 restricted: path >>
181 punct!(")") >>
182 (Visibility::Restricted(Box::new(restricted)))
183 )
184 |
David Tolnaybd76e572016-10-02 13:43:16 -0700185 keyword!("pub") => { |_| Visibility::Public }
David Tolnayf38cdf62016-09-23 19:07:09 -0700186 |
187 epsilon!() => { |_| Visibility::Inherited }
188 ));
David Tolnayf38cdf62016-09-23 19:07:09 -0700189}
190
191#[cfg(feature = "printing")]
192mod printing {
193 use super::*;
David Tolnayf38cdf62016-09-23 19:07:09 -0700194 use quote::{Tokens, ToTokens};
195
196 impl ToTokens for Variant {
197 fn to_tokens(&self, tokens: &mut Tokens) {
198 for attr in &self.attrs {
199 attr.to_tokens(tokens);
200 }
201 self.ident.to_tokens(tokens);
202 self.data.to_tokens(tokens);
203 if let Some(ref disr) = self.discriminant {
204 tokens.append("=");
205 disr.to_tokens(tokens);
206 }
207 }
208 }
209
210 impl ToTokens for VariantData {
211 fn to_tokens(&self, tokens: &mut Tokens) {
212 match *self {
213 VariantData::Struct(ref fields) => {
214 tokens.append("{");
215 tokens.append_separated(fields, ",");
216 tokens.append("}");
217 }
218 VariantData::Tuple(ref fields) => {
219 tokens.append("(");
220 tokens.append_separated(fields, ",");
221 tokens.append(")");
222 }
223 VariantData::Unit => {}
224 }
225 }
226 }
227
228 impl ToTokens for Field {
229 fn to_tokens(&self, tokens: &mut Tokens) {
230 for attr in &self.attrs {
231 attr.to_tokens(tokens);
232 }
David Tolnay47a877c2016-10-01 16:50:55 -0700233 self.vis.to_tokens(tokens);
David Tolnayf38cdf62016-09-23 19:07:09 -0700234 if let Some(ref ident) = self.ident {
235 ident.to_tokens(tokens);
236 tokens.append(":");
237 }
238 self.ty.to_tokens(tokens);
239 }
240 }
241
David Tolnay47a877c2016-10-01 16:50:55 -0700242 impl ToTokens for Visibility {
243 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaye07f9e02016-10-30 17:05:55 -0700244 match *self {
245 Visibility::Public => tokens.append("pub"),
246 Visibility::Crate => {
247 tokens.append("pub");
248 tokens.append("(");
249 tokens.append("crate");
250 tokens.append(")");
251 }
252 Visibility::Restricted(ref path) => {
253 tokens.append("pub");
254 tokens.append("(");
255 path.to_tokens(tokens);
256 tokens.append(")");
257 }
258 Visibility::Inherited => {}
David Tolnay47a877c2016-10-01 16:50:55 -0700259 }
260 }
261 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700262}