blob: 9e8e9b40e65cc95820e7727d72d2cbeb3843303f [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 Tolnay4a51dc72016-10-01 00:40:31 -070054 use attr::parsing::outer_attr;
David Tolnay3cb23a92016-10-07 23:02:21 -070055 use constant::parsing::const_expr;
David Tolnayf38cdf62016-09-23 19:07:09 -070056 use ident::parsing::ident;
David Tolnayf38cdf62016-09-23 19:07:09 -070057 use ty::parsing::ty;
David Tolnayf38cdf62016-09-23 19:07:09 -070058
59 named!(pub struct_body -> VariantData, alt!(
60 struct_like_body => { VariantData::Struct }
61 |
62 terminated!(tuple_like_body, punct!(";")) => { VariantData::Tuple }
63 |
64 punct!(";") => { |_| VariantData::Unit }
65 ));
66
67 named!(pub enum_body -> Vec<Variant>, do_parse!(
68 punct!("{") >>
David Tolnayff46fd22016-10-08 13:53:28 -070069 variants: terminated_list!(punct!(","), variant) >>
David Tolnayf38cdf62016-09-23 19:07:09 -070070 punct!("}") >>
71 (variants)
72 ));
73
74 named!(variant -> Variant, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -070075 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -070076 id: ident >>
77 data: alt!(
78 struct_like_body => { VariantData::Struct }
79 |
80 tuple_like_body => { VariantData::Tuple }
81 |
82 epsilon!() => { |_| VariantData::Unit }
83 ) >>
David Tolnay3cb23a92016-10-07 23:02:21 -070084 disr: option!(preceded!(punct!("="), const_expr)) >>
David Tolnayf38cdf62016-09-23 19:07:09 -070085 (Variant {
86 ident: id,
87 attrs: attrs,
88 data: data,
89 discriminant: disr,
90 })
91 ));
92
David Tolnay2f9fa632016-10-03 22:08:48 -070093 named!(pub struct_like_body -> Vec<Field>, do_parse!(
David Tolnayf38cdf62016-09-23 19:07:09 -070094 punct!("{") >>
David Tolnayff46fd22016-10-08 13:53:28 -070095 fields: terminated_list!(punct!(","), struct_field) >>
David Tolnayf38cdf62016-09-23 19:07:09 -070096 punct!("}") >>
97 (fields)
98 ));
99
100 named!(tuple_like_body -> Vec<Field>, do_parse!(
101 punct!("(") >>
David Tolnayff46fd22016-10-08 13:53:28 -0700102 fields: terminated_list!(punct!(","), tuple_field) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700103 punct!(")") >>
104 (fields)
105 ));
106
107 named!(struct_field -> Field, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700108 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700109 vis: visibility >>
110 id: ident >>
111 punct!(":") >>
112 ty: ty >>
113 (Field {
114 ident: Some(id),
115 vis: vis,
116 attrs: attrs,
117 ty: ty,
118 })
119 ));
120
121 named!(tuple_field -> Field, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -0700122 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -0700123 vis: visibility >>
124 ty: ty >>
125 (Field {
126 ident: None,
127 vis: vis,
128 attrs: attrs,
129 ty: ty,
130 })
131 ));
132
133 named!(pub visibility -> Visibility, alt!(
David Tolnaybd76e572016-10-02 13:43:16 -0700134 keyword!("pub") => { |_| Visibility::Public }
David Tolnayf38cdf62016-09-23 19:07:09 -0700135 |
136 epsilon!() => { |_| Visibility::Inherited }
137 ));
David Tolnayf38cdf62016-09-23 19:07:09 -0700138}
139
140#[cfg(feature = "printing")]
141mod printing {
142 use super::*;
David Tolnayf38cdf62016-09-23 19:07:09 -0700143 use quote::{Tokens, ToTokens};
144
145 impl ToTokens for Variant {
146 fn to_tokens(&self, tokens: &mut Tokens) {
147 for attr in &self.attrs {
148 attr.to_tokens(tokens);
149 }
150 self.ident.to_tokens(tokens);
151 self.data.to_tokens(tokens);
152 if let Some(ref disr) = self.discriminant {
153 tokens.append("=");
154 disr.to_tokens(tokens);
155 }
156 }
157 }
158
159 impl ToTokens for VariantData {
160 fn to_tokens(&self, tokens: &mut Tokens) {
161 match *self {
162 VariantData::Struct(ref fields) => {
163 tokens.append("{");
164 tokens.append_separated(fields, ",");
165 tokens.append("}");
166 }
167 VariantData::Tuple(ref fields) => {
168 tokens.append("(");
169 tokens.append_separated(fields, ",");
170 tokens.append(")");
171 }
172 VariantData::Unit => {}
173 }
174 }
175 }
176
177 impl ToTokens for Field {
178 fn to_tokens(&self, tokens: &mut Tokens) {
179 for attr in &self.attrs {
180 attr.to_tokens(tokens);
181 }
David Tolnay47a877c2016-10-01 16:50:55 -0700182 self.vis.to_tokens(tokens);
David Tolnayf38cdf62016-09-23 19:07:09 -0700183 if let Some(ref ident) = self.ident {
184 ident.to_tokens(tokens);
185 tokens.append(":");
186 }
187 self.ty.to_tokens(tokens);
188 }
189 }
190
David Tolnay47a877c2016-10-01 16:50:55 -0700191 impl ToTokens for Visibility {
192 fn to_tokens(&self, tokens: &mut Tokens) {
193 if let Visibility::Public = *self {
194 tokens.append("pub");
195 }
196 }
197 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700198}