blob: 26367dda6a2ef97c880eb20b8fd4a88401e9ef76 [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
45#[derive(Debug, Copy, Clone, Eq, PartialEq)]
46pub enum Visibility {
47 Public,
48 Inherited,
49}
50
David Tolnayf38cdf62016-09-23 19:07:09 -070051#[cfg(feature = "parsing")]
52pub mod parsing {
53 use super::*;
David Tolnay28c1db62016-10-27 22:48:18 -070054 use WhereClause;
David Tolnay4a51dc72016-10-01 00:40:31 -070055 use attr::parsing::outer_attr;
David Tolnay3cb23a92016-10-07 23:02:21 -070056 use constant::parsing::const_expr;
David Tolnay28c1db62016-10-27 22:48:18 -070057 use generics::parsing::where_clause;
David Tolnayf38cdf62016-09-23 19:07:09 -070058 use ident::parsing::ident;
David Tolnayf38cdf62016-09-23 19:07:09 -070059 use ty::parsing::ty;
David Tolnayf38cdf62016-09-23 19:07:09 -070060
David Tolnay28c1db62016-10-27 22:48:18 -070061 named!(pub struct_body -> (WhereClause, VariantData), alt!(
62 do_parse!(
63 wh: where_clause >>
64 body: struct_like_body >>
65 (wh, VariantData::Struct(body))
66 )
David Tolnayf38cdf62016-09-23 19:07:09 -070067 |
David Tolnay28c1db62016-10-27 22:48:18 -070068 do_parse!(
69 body: tuple_like_body >>
70 wh: where_clause >>
71 punct!(";") >>
72 (wh, VariantData::Tuple(body))
73 )
David Tolnayf38cdf62016-09-23 19:07:09 -070074 |
David Tolnay28c1db62016-10-27 22:48:18 -070075 do_parse!(
76 wh: where_clause >>
77 punct!(";") >>
78 (wh, VariantData::Unit)
79 )
David Tolnayf38cdf62016-09-23 19:07:09 -070080 ));
81
David Tolnay28c1db62016-10-27 22:48:18 -070082 named!(pub enum_body -> (WhereClause, Vec<Variant>), do_parse!(
83 wh: where_clause >>
David Tolnayf38cdf62016-09-23 19:07:09 -070084 punct!("{") >>
David Tolnayff46fd22016-10-08 13:53:28 -070085 variants: terminated_list!(punct!(","), variant) >>
David Tolnayf38cdf62016-09-23 19:07:09 -070086 punct!("}") >>
David Tolnay28c1db62016-10-27 22:48:18 -070087 (wh, variants)
David Tolnayf38cdf62016-09-23 19:07:09 -070088 ));
89
90 named!(variant -> Variant, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -070091 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -070092 id: ident >>
93 data: alt!(
94 struct_like_body => { VariantData::Struct }
95 |
96 tuple_like_body => { VariantData::Tuple }
97 |
98 epsilon!() => { |_| VariantData::Unit }
99 ) >>
David Tolnay3cb23a92016-10-07 23:02:21 -0700100 disr: option!(preceded!(punct!("="), const_expr)) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700101 (Variant {
102 ident: id,
103 attrs: attrs,
104 data: data,
105 discriminant: disr,
106 })
107 ));
108
David Tolnay2f9fa632016-10-03 22:08:48 -0700109 named!(pub struct_like_body -> Vec<Field>, do_parse!(
David Tolnayf38cdf62016-09-23 19:07:09 -0700110 punct!("{") >>
David Tolnayff46fd22016-10-08 13:53:28 -0700111 fields: terminated_list!(punct!(","), struct_field) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700112 punct!("}") >>
113 (fields)
114 ));
115
116 named!(tuple_like_body -> Vec<Field>, do_parse!(
117 punct!("(") >>
David Tolnayff46fd22016-10-08 13:53:28 -0700118 fields: terminated_list!(punct!(","), tuple_field) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700119 punct!(")") >>
120 (fields)
121 ));
122
123 named!(struct_field -> Field, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700124 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700125 vis: visibility >>
126 id: ident >>
127 punct!(":") >>
128 ty: ty >>
129 (Field {
130 ident: Some(id),
131 vis: vis,
132 attrs: attrs,
133 ty: ty,
134 })
135 ));
136
137 named!(tuple_field -> Field, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700138 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700139 vis: visibility >>
140 ty: ty >>
141 (Field {
142 ident: None,
143 vis: vis,
144 attrs: attrs,
145 ty: ty,
146 })
147 ));
148
149 named!(pub visibility -> Visibility, alt!(
David Tolnaybd76e572016-10-02 13:43:16 -0700150 keyword!("pub") => { |_| Visibility::Public }
David Tolnayf38cdf62016-09-23 19:07:09 -0700151 |
152 epsilon!() => { |_| Visibility::Inherited }
153 ));
David Tolnayf38cdf62016-09-23 19:07:09 -0700154}
155
156#[cfg(feature = "printing")]
157mod printing {
158 use super::*;
David Tolnayf38cdf62016-09-23 19:07:09 -0700159 use quote::{Tokens, ToTokens};
160
161 impl ToTokens for Variant {
162 fn to_tokens(&self, tokens: &mut Tokens) {
163 for attr in &self.attrs {
164 attr.to_tokens(tokens);
165 }
166 self.ident.to_tokens(tokens);
167 self.data.to_tokens(tokens);
168 if let Some(ref disr) = self.discriminant {
169 tokens.append("=");
170 disr.to_tokens(tokens);
171 }
172 }
173 }
174
175 impl ToTokens for VariantData {
176 fn to_tokens(&self, tokens: &mut Tokens) {
177 match *self {
178 VariantData::Struct(ref fields) => {
179 tokens.append("{");
180 tokens.append_separated(fields, ",");
181 tokens.append("}");
182 }
183 VariantData::Tuple(ref fields) => {
184 tokens.append("(");
185 tokens.append_separated(fields, ",");
186 tokens.append(")");
187 }
188 VariantData::Unit => {}
189 }
190 }
191 }
192
193 impl ToTokens for Field {
194 fn to_tokens(&self, tokens: &mut Tokens) {
195 for attr in &self.attrs {
196 attr.to_tokens(tokens);
197 }
David Tolnay47a877c2016-10-01 16:50:55 -0700198 self.vis.to_tokens(tokens);
David Tolnayf38cdf62016-09-23 19:07:09 -0700199 if let Some(ref ident) = self.ident {
200 ident.to_tokens(tokens);
201 tokens.append(":");
202 }
203 self.ty.to_tokens(tokens);
204 }
205 }
206
David Tolnay47a877c2016-10-01 16:50:55 -0700207 impl ToTokens for Visibility {
208 fn to_tokens(&self, tokens: &mut Tokens) {
209 if let Visibility::Public = *self {
210 tokens.append("pub");
211 }
212 }
213 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700214}