blob: 738d4a778d12f3f7b60de182ee8170b7cada7f0c [file] [log] [blame]
David Tolnayf38cdf62016-09-23 19:07:09 -07001use super::*;
2
3#[derive(Debug, Clone, Eq, PartialEq)]
4pub 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
12#[derive(Debug, Clone, Eq, PartialEq)]
13pub 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
37#[derive(Debug, Clone, Eq, PartialEq)]
38pub struct Field {
39 pub ident: Option<Ident>,
40 pub vis: Visibility,
41 pub attrs: Vec<Attribute>,
42 pub ty: Ty,
43}
44
David Tolnaye07f9e02016-10-30 17:05:55 -070045#[derive(Debug, Clone, Eq, PartialEq)]
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 Tolnay4a51dc72016-10-01 00:40:31 -070057 use attr::parsing::outer_attr;
David Tolnay3cb23a92016-10-07 23:02:21 -070058 use constant::parsing::const_expr;
David Tolnay28c1db62016-10-27 22:48:18 -070059 use generics::parsing::where_clause;
David Tolnayf38cdf62016-09-23 19:07:09 -070060 use ident::parsing::ident;
David Tolnaye07f9e02016-10-30 17:05:55 -070061 use ty::parsing::{path, ty};
David Tolnayf38cdf62016-09-23 19:07:09 -070062
David Tolnay28c1db62016-10-27 22:48:18 -070063 named!(pub struct_body -> (WhereClause, VariantData), alt!(
64 do_parse!(
65 wh: where_clause >>
66 body: struct_like_body >>
67 (wh, VariantData::Struct(body))
68 )
David Tolnayf38cdf62016-09-23 19:07:09 -070069 |
David Tolnay28c1db62016-10-27 22:48:18 -070070 do_parse!(
71 body: tuple_like_body >>
72 wh: where_clause >>
73 punct!(";") >>
74 (wh, VariantData::Tuple(body))
75 )
David Tolnayf38cdf62016-09-23 19:07:09 -070076 |
David Tolnay28c1db62016-10-27 22:48:18 -070077 do_parse!(
78 wh: where_clause >>
79 punct!(";") >>
80 (wh, VariantData::Unit)
81 )
David Tolnayf38cdf62016-09-23 19:07:09 -070082 ));
83
David Tolnay28c1db62016-10-27 22:48:18 -070084 named!(pub enum_body -> (WhereClause, Vec<Variant>), do_parse!(
85 wh: where_clause >>
David Tolnayf38cdf62016-09-23 19:07:09 -070086 punct!("{") >>
David Tolnayff46fd22016-10-08 13:53:28 -070087 variants: terminated_list!(punct!(","), variant) >>
David Tolnayf38cdf62016-09-23 19:07:09 -070088 punct!("}") >>
David Tolnay28c1db62016-10-27 22:48:18 -070089 (wh, variants)
David Tolnayf38cdf62016-09-23 19:07:09 -070090 ));
91
92 named!(variant -> Variant, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -070093 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -070094 id: ident >>
95 data: alt!(
96 struct_like_body => { VariantData::Struct }
97 |
98 tuple_like_body => { VariantData::Tuple }
99 |
100 epsilon!() => { |_| VariantData::Unit }
101 ) >>
David Tolnay3cb23a92016-10-07 23:02:21 -0700102 disr: option!(preceded!(punct!("="), const_expr)) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700103 (Variant {
104 ident: id,
105 attrs: attrs,
106 data: data,
107 discriminant: disr,
108 })
109 ));
110
David Tolnay2f9fa632016-10-03 22:08:48 -0700111 named!(pub struct_like_body -> Vec<Field>, do_parse!(
David Tolnayf38cdf62016-09-23 19:07:09 -0700112 punct!("{") >>
David Tolnayff46fd22016-10-08 13:53:28 -0700113 fields: terminated_list!(punct!(","), struct_field) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700114 punct!("}") >>
115 (fields)
116 ));
117
118 named!(tuple_like_body -> Vec<Field>, do_parse!(
119 punct!("(") >>
David Tolnayff46fd22016-10-08 13:53:28 -0700120 fields: terminated_list!(punct!(","), tuple_field) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700121 punct!(")") >>
122 (fields)
123 ));
124
125 named!(struct_field -> Field, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700126 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700127 vis: visibility >>
128 id: ident >>
129 punct!(":") >>
130 ty: ty >>
131 (Field {
132 ident: Some(id),
133 vis: vis,
134 attrs: attrs,
135 ty: ty,
136 })
137 ));
138
139 named!(tuple_field -> Field, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700140 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700141 vis: visibility >>
142 ty: ty >>
143 (Field {
144 ident: None,
145 vis: vis,
146 attrs: attrs,
147 ty: ty,
148 })
149 ));
150
151 named!(pub visibility -> Visibility, alt!(
David Tolnaye07f9e02016-10-30 17:05:55 -0700152 do_parse!(
153 keyword!("pub") >>
154 punct!("(") >>
155 keyword!("crate") >>
156 punct!(")") >>
157 (Visibility::Crate)
158 )
159 |
160 do_parse!(
161 keyword!("pub") >>
162 punct!("(") >>
163 restricted: path >>
164 punct!(")") >>
165 (Visibility::Restricted(Box::new(restricted)))
166 )
167 |
David Tolnaybd76e572016-10-02 13:43:16 -0700168 keyword!("pub") => { |_| Visibility::Public }
David Tolnayf38cdf62016-09-23 19:07:09 -0700169 |
170 epsilon!() => { |_| Visibility::Inherited }
171 ));
David Tolnayf38cdf62016-09-23 19:07:09 -0700172}
173
174#[cfg(feature = "printing")]
175mod printing {
176 use super::*;
David Tolnayf38cdf62016-09-23 19:07:09 -0700177 use quote::{Tokens, ToTokens};
178
179 impl ToTokens for Variant {
180 fn to_tokens(&self, tokens: &mut Tokens) {
181 for attr in &self.attrs {
182 attr.to_tokens(tokens);
183 }
184 self.ident.to_tokens(tokens);
185 self.data.to_tokens(tokens);
186 if let Some(ref disr) = self.discriminant {
187 tokens.append("=");
188 disr.to_tokens(tokens);
189 }
190 }
191 }
192
193 impl ToTokens for VariantData {
194 fn to_tokens(&self, tokens: &mut Tokens) {
195 match *self {
196 VariantData::Struct(ref fields) => {
197 tokens.append("{");
198 tokens.append_separated(fields, ",");
199 tokens.append("}");
200 }
201 VariantData::Tuple(ref fields) => {
202 tokens.append("(");
203 tokens.append_separated(fields, ",");
204 tokens.append(")");
205 }
206 VariantData::Unit => {}
207 }
208 }
209 }
210
211 impl ToTokens for Field {
212 fn to_tokens(&self, tokens: &mut Tokens) {
213 for attr in &self.attrs {
214 attr.to_tokens(tokens);
215 }
David Tolnay47a877c2016-10-01 16:50:55 -0700216 self.vis.to_tokens(tokens);
David Tolnayf38cdf62016-09-23 19:07:09 -0700217 if let Some(ref ident) = self.ident {
218 ident.to_tokens(tokens);
219 tokens.append(":");
220 }
221 self.ty.to_tokens(tokens);
222 }
223 }
224
David Tolnay47a877c2016-10-01 16:50:55 -0700225 impl ToTokens for Visibility {
226 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnaye07f9e02016-10-30 17:05:55 -0700227 match *self {
228 Visibility::Public => tokens.append("pub"),
229 Visibility::Crate => {
230 tokens.append("pub");
231 tokens.append("(");
232 tokens.append("crate");
233 tokens.append(")");
234 }
235 Visibility::Restricted(ref path) => {
236 tokens.append("pub");
237 tokens.append("(");
238 path.to_tokens(tokens);
239 tokens.append(")");
240 }
241 Visibility::Inherited => {}
David Tolnay47a877c2016-10-01 16:50:55 -0700242 }
243 }
244 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700245}