blob: 536ba9d78685306ed7af3bb89fb490e1b139e0b0 [file] [log] [blame]
David Tolnayf38cdf62016-09-23 19:07:09 -07001use super::*;
2
3#[derive(Debug, Clone, Eq, PartialEq)]
4pub struct MacroInput {
5 pub ident: Ident,
6 pub vis: Visibility,
7 pub attrs: Vec<Attribute>,
8 pub generics: Generics,
9 pub body: Body,
10}
11
12#[derive(Debug, Clone, Eq, PartialEq)]
13pub enum Body {
14 Enum(Vec<Variant>),
15 Struct(VariantData),
16}
17
18#[cfg(feature = "parsing")]
19pub mod parsing {
20 use super::*;
21 use attr::parsing::attribute;
22 use data::parsing::{visibility, struct_body, enum_body};
23 use generics::parsing::generics;
24 use ident::parsing::ident;
25 use nom::multispace;
26
27 named!(pub macro_input -> MacroInput, do_parse!(
28 attrs: many0!(attribute) >>
29 vis: visibility >>
30 which: alt!(punct!("struct") | punct!("enum")) >>
31 multispace >>
32 id: ident >>
33 generics: generics >>
34 item: switch!(value!(which),
35 "struct" => map!(struct_body, move |body| MacroInput {
36 ident: id,
37 vis: vis,
38 attrs: attrs,
39 generics: generics,
40 body: Body::Struct(body),
41 })
42 |
43 "enum" => map!(enum_body, move |body| MacroInput {
44 ident: id,
45 vis: vis,
46 attrs: attrs,
47 generics: generics,
48 body: Body::Enum(body),
49 })
50 ) >>
51 option!(multispace) >>
52 (item)
53 ));
54}
55
56mod printing {
57 use super::*;
58 use data::{Visibility, VariantData};
59 use quote::{Tokens, ToTokens};
60
61 impl ToTokens for MacroInput {
62 fn to_tokens(&self, tokens: &mut Tokens) {
63 for attr in &self.attrs {
64 attr.to_tokens(tokens);
65 }
66 if let Visibility::Public = self.vis {
67 tokens.append("pub");
68 }
69 match self.body {
70 Body::Enum(_) => tokens.append("enum"),
71 Body::Struct(_) => tokens.append("struct"),
72 }
73 self.ident.to_tokens(tokens);
74 self.generics.to_tokens(tokens);
75 self.generics.where_clause.to_tokens(tokens);
76 self.body.to_tokens(tokens);
77 }
78 }
79
80 impl ToTokens for Body {
81 fn to_tokens(&self, tokens: &mut Tokens) {
82 match *self {
83 Body::Enum(ref variants) => {
84 tokens.append("{");
85 for variant in variants {
86 variant.to_tokens(tokens);
87 tokens.append(",");
88 }
89 tokens.append("}");
90 }
91 Body::Struct(ref variant_data) => {
92 variant_data.to_tokens(tokens);
93 match *variant_data {
94 VariantData::Struct(_) => { /* no semicolon */ }
95 VariantData::Tuple(_) |
96 VariantData::Unit => tokens.append(";"),
97 }
98 }
99 }
100 }
101 }
102}