blob: 306c352a53c77297f8bc25b006e7f15eb971c327 [file] [log] [blame]
David Tolnayf38cdf62016-09-23 19:07:09 -07001use super::*;
2
Clar Charrd22b5702017-03-10 15:24:56 -05003/// Struct or enum sent to a `proc_macro_derive` macro.
David Tolnay9bf4af82017-01-07 11:17:46 -08004#[derive(Debug, Clone, Eq, PartialEq, Hash)]
David Tolnay0e837402016-12-22 17:25:55 -05005pub struct DeriveInput {
Clar Charrd22b5702017-03-10 15:24:56 -05006 /// Name of the struct or enum.
David Tolnayf38cdf62016-09-23 19:07:09 -07007 pub ident: Ident,
Clar Charrd22b5702017-03-10 15:24:56 -05008
9 /// Visibility of the struct or enum.
David Tolnayf38cdf62016-09-23 19:07:09 -070010 pub vis: Visibility,
Clar Charrd22b5702017-03-10 15:24:56 -050011
12 /// Attributes tagged on the whole struct or enum.
David Tolnayf38cdf62016-09-23 19:07:09 -070013 pub attrs: Vec<Attribute>,
Clar Charrd22b5702017-03-10 15:24:56 -050014
15 /// Generics required to complete the definition.
David Tolnayf38cdf62016-09-23 19:07:09 -070016 pub generics: Generics,
Clar Charrd22b5702017-03-10 15:24:56 -050017
18 /// Data within the struct or enum.
David Tolnayf38cdf62016-09-23 19:07:09 -070019 pub body: Body,
20}
21
Clar Charrd22b5702017-03-10 15:24:56 -050022/// Body of a derived struct or enum.
David Tolnay9bf4af82017-01-07 11:17:46 -080023#[derive(Debug, Clone, Eq, PartialEq, Hash)]
David Tolnayf38cdf62016-09-23 19:07:09 -070024pub enum Body {
Clar Charrd22b5702017-03-10 15:24:56 -050025 /// It's an enum.
David Tolnayf38cdf62016-09-23 19:07:09 -070026 Enum(Vec<Variant>),
Clar Charrd22b5702017-03-10 15:24:56 -050027
28 /// It's a struct.
David Tolnayf38cdf62016-09-23 19:07:09 -070029 Struct(VariantData),
30}
31
32#[cfg(feature = "parsing")]
33pub mod parsing {
34 use super::*;
David Tolnay3cf52982016-10-01 17:11:37 -070035 use Generics;
David Tolnay4a51dc72016-10-01 00:40:31 -070036 use attr::parsing::outer_attr;
David Tolnayf38cdf62016-09-23 19:07:09 -070037 use data::parsing::{visibility, struct_body, enum_body};
David Tolnay28c1db62016-10-27 22:48:18 -070038 use generics::parsing::generics;
David Tolnayf38cdf62016-09-23 19:07:09 -070039 use ident::parsing::ident;
David Tolnayf38cdf62016-09-23 19:07:09 -070040
David Tolnay0e837402016-12-22 17:25:55 -050041 named!(pub derive_input -> DeriveInput, do_parse!(
David Tolnay4a51dc72016-10-01 00:40:31 -070042 attrs: many0!(outer_attr) >>
David Tolnayf38cdf62016-09-23 19:07:09 -070043 vis: visibility >>
David Tolnay10413f02016-09-30 09:12:02 -070044 which: alt!(keyword!("struct") | keyword!("enum")) >>
David Tolnayf38cdf62016-09-23 19:07:09 -070045 id: ident >>
46 generics: generics >>
47 item: switch!(value!(which),
David Tolnay0e837402016-12-22 17:25:55 -050048 "struct" => map!(struct_body, move |(wh, body)| DeriveInput {
David Tolnayf38cdf62016-09-23 19:07:09 -070049 ident: id,
50 vis: vis,
51 attrs: attrs,
David Tolnay3cf52982016-10-01 17:11:37 -070052 generics: Generics {
David Tolnay28c1db62016-10-27 22:48:18 -070053 where_clause: wh,
David Tolnay3cf52982016-10-01 17:11:37 -070054 .. generics
55 },
David Tolnayf38cdf62016-09-23 19:07:09 -070056 body: Body::Struct(body),
57 })
58 |
David Tolnay0e837402016-12-22 17:25:55 -050059 "enum" => map!(enum_body, move |(wh, body)| DeriveInput {
David Tolnayf38cdf62016-09-23 19:07:09 -070060 ident: id,
61 vis: vis,
62 attrs: attrs,
David Tolnay3cf52982016-10-01 17:11:37 -070063 generics: Generics {
David Tolnay28c1db62016-10-27 22:48:18 -070064 where_clause: wh,
David Tolnay3cf52982016-10-01 17:11:37 -070065 .. generics
66 },
David Tolnayf38cdf62016-09-23 19:07:09 -070067 body: Body::Enum(body),
68 })
69 ) >>
David Tolnayf38cdf62016-09-23 19:07:09 -070070 (item)
71 ));
72}
73
David Tolnayc2dfbf42016-09-23 23:52:15 -070074#[cfg(feature = "printing")]
David Tolnayf38cdf62016-09-23 19:07:09 -070075mod printing {
76 use super::*;
David Tolnay4a51dc72016-10-01 00:40:31 -070077 use attr::FilterAttrs;
David Tolnay47a877c2016-10-01 16:50:55 -070078 use data::VariantData;
David Tolnayf38cdf62016-09-23 19:07:09 -070079 use quote::{Tokens, ToTokens};
80
David Tolnay0e837402016-12-22 17:25:55 -050081 impl ToTokens for DeriveInput {
David Tolnayf38cdf62016-09-23 19:07:09 -070082 fn to_tokens(&self, tokens: &mut Tokens) {
David Tolnay4a51dc72016-10-01 00:40:31 -070083 for attr in self.attrs.outer() {
David Tolnayf38cdf62016-09-23 19:07:09 -070084 attr.to_tokens(tokens);
85 }
David Tolnay47a877c2016-10-01 16:50:55 -070086 self.vis.to_tokens(tokens);
David Tolnayf38cdf62016-09-23 19:07:09 -070087 match self.body {
88 Body::Enum(_) => tokens.append("enum"),
89 Body::Struct(_) => tokens.append("struct"),
90 }
91 self.ident.to_tokens(tokens);
92 self.generics.to_tokens(tokens);
David Tolnay28c1db62016-10-27 22:48:18 -070093 match self.body {
David Tolnayf38cdf62016-09-23 19:07:09 -070094 Body::Enum(ref variants) => {
David Tolnay28c1db62016-10-27 22:48:18 -070095 self.generics.where_clause.to_tokens(tokens);
David Tolnayf38cdf62016-09-23 19:07:09 -070096 tokens.append("{");
97 for variant in variants {
98 variant.to_tokens(tokens);
99 tokens.append(",");
100 }
101 tokens.append("}");
102 }
103 Body::Struct(ref variant_data) => {
David Tolnayf38cdf62016-09-23 19:07:09 -0700104 match *variant_data {
David Tolnaydaaf7742016-10-03 11:11:43 -0700105 VariantData::Struct(_) => {
David Tolnay28c1db62016-10-27 22:48:18 -0700106 self.generics.where_clause.to_tokens(tokens);
107 variant_data.to_tokens(tokens);
David Tolnaydaaf7742016-10-03 11:11:43 -0700108 // no semicolon
109 }
David Tolnay28c1db62016-10-27 22:48:18 -0700110 VariantData::Tuple(_) => {
111 variant_data.to_tokens(tokens);
112 self.generics.where_clause.to_tokens(tokens);
113 tokens.append(";");
114 }
115 VariantData::Unit => {
116 self.generics.where_clause.to_tokens(tokens);
117 tokens.append(";");
118 }
David Tolnayf38cdf62016-09-23 19:07:09 -0700119 }
120 }
121 }
122 }
123 }
124}