blob: c1ae79c08976ec2fa36bce9b7fca521567ff5ab3 [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 Tolnayf945fb52017-02-27 12:53:54 -080060 #[cfg(feature = "full")]
David Tolnay3cb23a92016-10-07 23:02:21 -070061 use constant::parsing::const_expr;
David Tolnay514f1292017-02-27 12:30:57 -080062 #[cfg(feature = "full")]
63 use expr::parsing::expr;
David Tolnay28c1db62016-10-27 22:48:18 -070064 use generics::parsing::where_clause;
David Tolnayf38cdf62016-09-23 19:07:09 -070065 use ident::parsing::ident;
David Tolnaye07f9e02016-10-30 17:05:55 -070066 use ty::parsing::{path, ty};
David Tolnayf38cdf62016-09-23 19:07:09 -070067
David Tolnay28c1db62016-10-27 22:48:18 -070068 named!(pub struct_body -> (WhereClause, VariantData), alt!(
69 do_parse!(
70 wh: where_clause >>
71 body: struct_like_body >>
72 (wh, VariantData::Struct(body))
73 )
David Tolnayf38cdf62016-09-23 19:07:09 -070074 |
David Tolnay28c1db62016-10-27 22:48:18 -070075 do_parse!(
76 body: tuple_like_body >>
77 wh: where_clause >>
78 punct!(";") >>
79 (wh, VariantData::Tuple(body))
80 )
David Tolnayf38cdf62016-09-23 19:07:09 -070081 |
David Tolnay28c1db62016-10-27 22:48:18 -070082 do_parse!(
83 wh: where_clause >>
84 punct!(";") >>
85 (wh, VariantData::Unit)
86 )
David Tolnayf38cdf62016-09-23 19:07:09 -070087 ));
88
David Tolnay28c1db62016-10-27 22:48:18 -070089 named!(pub enum_body -> (WhereClause, Vec<Variant>), do_parse!(
90 wh: where_clause >>
David Tolnayf38cdf62016-09-23 19:07:09 -070091 punct!("{") >>
David Tolnayff46fd22016-10-08 13:53:28 -070092 variants: terminated_list!(punct!(","), variant) >>
David Tolnayf38cdf62016-09-23 19:07:09 -070093 punct!("}") >>
David Tolnay28c1db62016-10-27 22:48:18 -070094 (wh, variants)
David Tolnayf38cdf62016-09-23 19:07:09 -070095 ));
96
97 named!(variant -> Variant, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -070098 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -070099 id: ident >>
100 data: alt!(
101 struct_like_body => { VariantData::Struct }
102 |
103 tuple_like_body => { VariantData::Tuple }
104 |
105 epsilon!() => { |_| VariantData::Unit }
106 ) >>
David Tolnay514f1292017-02-27 12:30:57 -0800107 disr: option!(preceded!(punct!("="), discriminant)) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700108 (Variant {
109 ident: id,
110 attrs: attrs,
111 data: data,
112 discriminant: disr,
113 })
114 ));
115
David Tolnay514f1292017-02-27 12:30:57 -0800116 #[cfg(not(feature = "full"))]
David Tolnayf945fb52017-02-27 12:53:54 -0800117 use constant::parsing::const_expr as discriminant;
David Tolnay514f1292017-02-27 12:30:57 -0800118
119 #[cfg(feature = "full")]
120 named!(discriminant -> ConstExpr, alt!(
121 terminated!(const_expr, after_discriminant)
122 |
123 terminated!(expr, after_discriminant) => { ConstExpr::Other }
124 ));
125
126 #[cfg(feature = "full")]
127 named!(after_discriminant -> &str, peek!(alt!(punct!(",") | punct!("}"))));
128
David Tolnay2f9fa632016-10-03 22:08:48 -0700129 named!(pub struct_like_body -> Vec<Field>, do_parse!(
David Tolnayf38cdf62016-09-23 19:07:09 -0700130 punct!("{") >>
David Tolnayff46fd22016-10-08 13:53:28 -0700131 fields: terminated_list!(punct!(","), struct_field) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700132 punct!("}") >>
133 (fields)
134 ));
135
136 named!(tuple_like_body -> Vec<Field>, do_parse!(
137 punct!("(") >>
David Tolnayff46fd22016-10-08 13:53:28 -0700138 fields: terminated_list!(punct!(","), tuple_field) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700139 punct!(")") >>
140 (fields)
141 ));
142
143 named!(struct_field -> Field, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700144 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700145 vis: visibility >>
146 id: ident >>
147 punct!(":") >>
148 ty: ty >>
149 (Field {
150 ident: Some(id),
151 vis: vis,
152 attrs: attrs,
153 ty: ty,
154 })
155 ));
156
157 named!(tuple_field -> Field, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700158 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700159 vis: visibility >>
160 ty: ty >>
161 (Field {
162 ident: None,
163 vis: vis,
164 attrs: attrs,
165 ty: ty,
166 })
167 ));
168
169 named!(pub visibility -> Visibility, alt!(
David Tolnaye07f9e02016-10-30 17:05:55 -0700170 do_parse!(
171 keyword!("pub") >>
172 punct!("(") >>
173 keyword!("crate") >>
174 punct!(")") >>
175 (Visibility::Crate)
176 )
177 |
178 do_parse!(
179 keyword!("pub") >>
180 punct!("(") >>
181 restricted: path >>
182 punct!(")") >>
183 (Visibility::Restricted(Box::new(restricted)))
184 )
185 |
David Tolnaybd76e572016-10-02 13:43:16 -0700186 keyword!("pub") => { |_| Visibility::Public }
David Tolnayf38cdf62016-09-23 19:07:09 -0700187 |
188 epsilon!() => { |_| Visibility::Inherited }
189 ));
David Tolnayf38cdf62016-09-23 19:07:09 -0700190}
191
192#[cfg(feature = "printing")]
193mod printing {
194 use super::*;
David Tolnayf38cdf62016-09-23 19:07:09 -0700195 use quote::{Tokens, ToTokens};
196
197 impl ToTokens for Variant {
198 fn to_tokens(&self, tokens: &mut Tokens) {
199 for attr in &self.attrs {
200 attr.to_tokens(tokens);
201 }
202 self.ident.to_tokens(tokens);
203 self.data.to_tokens(tokens);
204 if let Some(ref disr) = self.discriminant {
205 tokens.append("=");
206 disr.to_tokens(tokens);
207 }
208 }
209 }
210
211 impl ToTokens for VariantData {
212 fn to_tokens(&self, tokens: &mut Tokens) {
213 match *self {
214 VariantData::Struct(ref fields) => {
215 tokens.append("{");
216 tokens.append_separated(fields, ",");
217 tokens.append("}");
218 }
219 VariantData::Tuple(ref fields) => {
220 tokens.append("(");
221 tokens.append_separated(fields, ",");
222 tokens.append(")");
223 }
224 VariantData::Unit => {}
225 }
226 }
227 }
228
229 impl ToTokens for Field {
230 fn to_tokens(&self, tokens: &mut Tokens) {
231 for attr in &self.attrs {
232 attr.to_tokens(tokens);
233 }
David Tolnay47a877c2016-10-01 16:50:55 -0700234 self.vis.to_tokens(tokens);
David Tolnayf38cdf62016-09-23 19:07:09 -0700235 if let Some(ref ident) = self.ident {
236 ident.to_tokens(tokens);
237 tokens.append(":");
238 }
239 self.ty.to_tokens(tokens);
240 }
241 }
242
David Tolnay47a877c2016-10-01 16:50:55 -0700243 impl ToTokens for Visibility {
244 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaye07f9e02016-10-30 17:05:55 -0700245 match *self {
246 Visibility::Public => tokens.append("pub"),
247 Visibility::Crate => {
248 tokens.append("pub");
249 tokens.append("(");
250 tokens.append("crate");
251 tokens.append(")");
252 }
253 Visibility::Restricted(ref path) => {
254 tokens.append("pub");
255 tokens.append("(");
256 path.to_tokens(tokens);
257 tokens.append(")");
258 }
259 Visibility::Inherited => {}
David Tolnay47a877c2016-10-01 16:50:55 -0700260 }
261 }
262 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700263}