1 use super::*; 2 3 /// Struct or enum sent to a `proc_macro_derive` macro. 4 #[derive(Debug, Clone, Eq, PartialEq, Hash)] 5 pub struct DeriveInput { 6 /// Name of the struct or enum. 7 pub ident: Ident, 8 9 /// Visibility of the struct or enum. 10 pub vis: Visibility, 11 12 /// Attributes tagged on the whole struct or enum. 13 pub attrs: Vec<Attribute>, 14 15 /// Generics required to complete the definition. 16 pub generics: Generics, 17 18 /// Data within the struct or enum. 19 pub body: Body, 20 } 21 22 /// Body of a derived struct or enum. 23 #[derive(Debug, Clone, Eq, PartialEq, Hash)] 24 pub enum Body { 25 /// It's an enum. 26 Enum(Vec<Variant>), 27 28 /// It's a struct. 29 Struct(VariantData), 30 } 31 32 #[cfg(feature = "parsing")] 33 pub mod parsing { 34 use super::*; 35 use Generics; 36 use attr::parsing::outer_attr; 37 use data::parsing::{visibility, struct_body, enum_body}; 38 use generics::parsing::generics; 39 use ident::parsing::ident; 40 41 named!(pub derive_input -> DeriveInput, do_parse!( 42 attrs: many0!(outer_attr) >> 43 vis: visibility >> 44 which: alt!(keyword!("struct") | keyword!("enum")) >> 45 id: ident >> 46 generics: generics >> 47 item: switch!(value!(which), 48 "struct" => map!(struct_body, move |(wh, body)| DeriveInput { 49 ident: id, 50 vis: vis, 51 attrs: attrs, 52 generics: Generics { 53 where_clause: wh, 54 .. generics 55 }, 56 body: Body::Struct(body), 57 }) 58 | 59 "enum" => map!(enum_body, move |(wh, body)| DeriveInput { 60 ident: id, 61 vis: vis, 62 attrs: attrs, 63 generics: Generics { 64 where_clause: wh, 65 .. generics 66 }, 67 body: Body::Enum(body), 68 }) 69 ) >> 70 (item) 71 )); 72 } 73 74 #[cfg(feature = "printing")] 75 mod printing { 76 use super::*; 77 use attr::FilterAttrs; 78 use data::VariantData; 79 use quote::{Tokens, ToTokens}; 80 81 impl ToTokens for DeriveInput { to_tokens(&self, tokens: &mut Tokens)82 fn to_tokens(&self, tokens: &mut Tokens) { 83 for attr in self.attrs.outer() { 84 attr.to_tokens(tokens); 85 } 86 self.vis.to_tokens(tokens); 87 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); 93 match self.body { 94 Body::Enum(ref variants) => { 95 self.generics.where_clause.to_tokens(tokens); 96 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) => { 104 match *variant_data { 105 VariantData::Struct(_) => { 106 self.generics.where_clause.to_tokens(tokens); 107 variant_data.to_tokens(tokens); 108 // no semicolon 109 } 110 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 } 119 } 120 } 121 } 122 } 123 } 124 } 125