blob: 7b5852320fb46577a46a0049a88ca09ee5ae0107 [file] [log] [blame]
David Tolnayf38cdf62016-09-23 19:07:09 -07001use super::*;
Alex Crichtonccbb45d2017-05-23 10:58:24 -07002use delimited::Delimited;
David Tolnayf38cdf62016-09-23 19:07:09 -07003
Alex Crichton62a0a592017-05-22 13:58:53 -07004ast_struct! {
David Tolnaye3d41b72017-12-31 15:24:00 -05005 /// Data structure sent to a `proc_macro_derive` macro.
Alex Crichton62a0a592017-05-22 13:58:53 -07006 pub struct DeriveInput {
David Tolnay4a3f59a2017-12-28 21:21:12 -05007 /// Attributes tagged on the whole struct or enum.
8 pub attrs: Vec<Attribute>,
Clar Charrd22b5702017-03-10 15:24:56 -05009
Alex Crichton62a0a592017-05-22 13:58:53 -070010 /// Visibility of the struct or enum.
11 pub vis: Visibility,
Clar Charrd22b5702017-03-10 15:24:56 -050012
David Tolnay4a3f59a2017-12-28 21:21:12 -050013 /// Name of the struct or enum.
14 pub ident: Ident,
Clar Charrd22b5702017-03-10 15:24:56 -050015
Alex Crichton62a0a592017-05-22 13:58:53 -070016 /// Generics required to complete the definition.
17 pub generics: Generics,
Clar Charrd22b5702017-03-10 15:24:56 -050018
Alex Crichton62a0a592017-05-22 13:58:53 -070019 /// Data within the struct or enum.
David Tolnaye3d41b72017-12-31 15:24:00 -050020 pub data: Data,
Alex Crichton62a0a592017-05-22 13:58:53 -070021 }
David Tolnayf38cdf62016-09-23 19:07:09 -070022}
23
Alex Crichtonccbb45d2017-05-23 10:58:24 -070024ast_enum_of_structs! {
David Tolnaye3d41b72017-12-31 15:24:00 -050025 /// The storage of a struct, enum or union data structure.
26 pub enum Data {
27 /// It's a struct.
28 pub Struct(DataStruct {
29 pub struct_token: Token![struct],
30 pub fields: Fields,
31 pub semi_token: Option<Token![;]>,
32 }),
33
Alex Crichton62a0a592017-05-22 13:58:53 -070034 /// It's an enum.
David Tolnaye3d41b72017-12-31 15:24:00 -050035 pub Enum(DataEnum {
David Tolnayf8db7ba2017-11-11 22:52:16 -080036 pub enum_token: Token![enum],
David Tolnay32954ef2017-12-26 22:43:16 -050037 pub brace_token: token::Brace,
David Tolnayf8db7ba2017-11-11 22:52:16 -080038 pub variants: Delimited<Variant, Token![,]>,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070039 }),
Alex Crichton62a0a592017-05-22 13:58:53 -070040
David Tolnaye3d41b72017-12-31 15:24:00 -050041 /// It's an untagged union.
42 pub Union(DataUnion {
43 pub union_token: Token![union],
44 pub fields: FieldsNamed,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070045 }),
Alex Crichton62a0a592017-05-22 13:58:53 -070046 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -070047
48 do_not_generate_to_tokens
David Tolnayf38cdf62016-09-23 19:07:09 -070049}
50
51#[cfg(feature = "parsing")]
52pub mod parsing {
53 use super::*;
David Tolnayf38cdf62016-09-23 19:07:09 -070054
Michael Layzell92639a52017-06-01 00:07:44 -040055 use synom::Synom;
Alex Crichton954046c2017-05-30 21:49:42 -070056
57 impl Synom for DeriveInput {
Michael Layzell92639a52017-06-01 00:07:44 -040058 named!(parse -> Self, do_parse!(
David Tolnay2c136452017-12-27 14:13:32 -050059 attrs: many0!(Attribute::parse_outer) >>
Michael Layzell92639a52017-06-01 00:07:44 -040060 vis: syn!(Visibility) >>
61 which: alt!(
David Tolnayf8db7ba2017-11-11 22:52:16 -080062 keyword!(struct) => { Ok }
Michael Layzell92639a52017-06-01 00:07:44 -040063 |
David Tolnayf8db7ba2017-11-11 22:52:16 -080064 keyword!(enum) => { Err }
Michael Layzell92639a52017-06-01 00:07:44 -040065 ) >>
66 id: syn!(Ident) >>
67 generics: syn!(Generics) >>
68 item: switch!(value!(which),
David Tolnaye3d41b72017-12-31 15:24:00 -050069 Ok(s) => map!(data_struct, move |(wh, fields, semi)| DeriveInput {
Michael Layzell92639a52017-06-01 00:07:44 -040070 ident: id,
71 vis: vis,
72 attrs: attrs,
73 generics: Generics {
74 where_clause: wh,
75 .. generics
76 },
David Tolnaye3d41b72017-12-31 15:24:00 -050077 data: Data::Struct(DataStruct {
Michael Layzell92639a52017-06-01 00:07:44 -040078 struct_token: s,
David Tolnaye3d41b72017-12-31 15:24:00 -050079 fields: fields,
Michael Layzell92639a52017-06-01 00:07:44 -040080 semi_token: semi,
81 }),
82 })
83 |
David Tolnaye3d41b72017-12-31 15:24:00 -050084 Err(e) => map!(data_enum, move |(wh, brace, variants)| DeriveInput {
Michael Layzell92639a52017-06-01 00:07:44 -040085 ident: id,
86 vis: vis,
87 attrs: attrs,
88 generics: Generics {
89 where_clause: wh,
90 .. generics
91 },
David Tolnaye3d41b72017-12-31 15:24:00 -050092 data: Data::Enum(DataEnum {
93 variants: variants,
Michael Layzell92639a52017-06-01 00:07:44 -040094 brace_token: brace,
95 enum_token: e,
96 }),
97 })
98 ) >>
99 (item)
100 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700101
102 fn description() -> Option<&'static str> {
103 Some("derive input")
104 }
105 }
106
David Tolnaye3d41b72017-12-31 15:24:00 -0500107 named!(data_struct -> (Option<WhereClause>, Fields, Option<Token![;]>), alt!(
Alex Crichton954046c2017-05-30 21:49:42 -0700108 do_parse!(
David Tolnayac997dd2017-12-27 23:18:22 -0500109 wh: option!(syn!(WhereClause)) >>
David Tolnaye3d41b72017-12-31 15:24:00 -0500110 fields: syn!(FieldsNamed) >>
111 (wh, Fields::Named(fields), None)
Alex Crichton954046c2017-05-30 21:49:42 -0700112 )
113 |
114 do_parse!(
David Tolnaye3d41b72017-12-31 15:24:00 -0500115 fields: syn!(FieldsUnnamed) >>
David Tolnayac997dd2017-12-27 23:18:22 -0500116 wh: option!(syn!(WhereClause)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800117 semi: punct!(;) >>
David Tolnaye3d41b72017-12-31 15:24:00 -0500118 (wh, Fields::Unnamed(fields), Some(semi))
Alex Crichton954046c2017-05-30 21:49:42 -0700119 )
120 |
121 do_parse!(
David Tolnayac997dd2017-12-27 23:18:22 -0500122 wh: option!(syn!(WhereClause)) >>
David Tolnayf8db7ba2017-11-11 22:52:16 -0800123 semi: punct!(;) >>
David Tolnaye3d41b72017-12-31 15:24:00 -0500124 (wh, Fields::Unit, Some(semi))
Alex Crichton954046c2017-05-30 21:49:42 -0700125 )
David Tolnayf38cdf62016-09-23 19:07:09 -0700126 ));
Alex Crichton954046c2017-05-30 21:49:42 -0700127
David Tolnaye3d41b72017-12-31 15:24:00 -0500128 named!(data_enum -> (Option<WhereClause>, token::Brace, Delimited<Variant, Token![,]>), do_parse!(
David Tolnayac997dd2017-12-27 23:18:22 -0500129 wh: option!(syn!(WhereClause)) >>
Alex Crichton954046c2017-05-30 21:49:42 -0700130 data: braces!(Delimited::parse_terminated) >>
131 (wh, data.0, data.1)
132 ));
David Tolnayf38cdf62016-09-23 19:07:09 -0700133}
134
David Tolnayc2dfbf42016-09-23 23:52:15 -0700135#[cfg(feature = "printing")]
David Tolnayf38cdf62016-09-23 19:07:09 -0700136mod printing {
137 use super::*;
David Tolnay4a51dc72016-10-01 00:40:31 -0700138 use attr::FilterAttrs;
David Tolnay51382052017-12-27 13:46:21 -0500139 use quote::{ToTokens, Tokens};
David Tolnayf38cdf62016-09-23 19:07:09 -0700140
David Tolnay0e837402016-12-22 17:25:55 -0500141 impl ToTokens for DeriveInput {
David Tolnayf38cdf62016-09-23 19:07:09 -0700142 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay4a51dc72016-10-01 00:40:31 -0700143 for attr in self.attrs.outer() {
David Tolnayf38cdf62016-09-23 19:07:09 -0700144 attr.to_tokens(tokens);
145 }
David Tolnay47a877c2016-10-01 16:50:55 -0700146 self.vis.to_tokens(tokens);
David Tolnaye3d41b72017-12-31 15:24:00 -0500147 match self.data {
148 Data::Struct(ref d) => d.struct_token.to_tokens(tokens),
149 Data::Enum(ref d) => d.enum_token.to_tokens(tokens),
150 Data::Union(ref d) => d.union_token.to_tokens(tokens),
David Tolnayf38cdf62016-09-23 19:07:09 -0700151 }
152 self.ident.to_tokens(tokens);
153 self.generics.to_tokens(tokens);
David Tolnaye3d41b72017-12-31 15:24:00 -0500154 match self.data {
155 Data::Struct(ref data) => {
156 match data.fields {
157 Fields::Named(ref fields) => {
158 self.generics.where_clause.to_tokens(tokens);
159 fields.to_tokens(tokens);
160 }
161 Fields::Unnamed(ref fields) => {
162 fields.to_tokens(tokens);
163 self.generics.where_clause.to_tokens(tokens);
164 TokensOrDefault(&data.semi_token).to_tokens(tokens);
165 }
166 Fields::Unit => {
167 self.generics.where_clause.to_tokens(tokens);
168 TokensOrDefault(&data.semi_token).to_tokens(tokens);
169 }
170 }
171 }
172 Data::Enum(ref data) => {
David Tolnay28c1db62016-10-27 22:48:18 -0700173 self.generics.where_clause.to_tokens(tokens);
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700174 data.brace_token.surround(tokens, |tokens| {
175 data.variants.to_tokens(tokens);
176 });
David Tolnayf38cdf62016-09-23 19:07:09 -0700177 }
David Tolnaye3d41b72017-12-31 15:24:00 -0500178 Data::Union(ref data) => {
179 self.generics.where_clause.to_tokens(tokens);
180 data.fields.to_tokens(tokens);
David Tolnayf38cdf62016-09-23 19:07:09 -0700181 }
182 }
183 }
184 }
185}