enum_dispatch/
enum_dispatch_item.rs
1use quote::TokenStreamExt;
10
11use crate::enum_dispatch_variant::EnumDispatchVariant;
12use crate::filter_attrs::FilterAttrs;
13
14#[derive(Clone)]
18pub struct EnumDispatchItem {
19 pub attrs: Vec<syn::Attribute>,
20 pub vis: syn::Visibility,
21 enum_token: syn::token::Enum,
22 pub ident: syn::Ident,
23 pub generics: syn::Generics,
24 brace_token: syn::token::Brace,
25 pub variants: syn::punctuated::Punctuated<EnumDispatchVariant, syn::token::Comma>,
26}
27
28impl syn::parse::Parse for EnumDispatchItem {
30 fn parse(input: syn::parse::ParseStream) -> syn::parse::Result<Self> {
31 let attrs = input.call(syn::Attribute::parse_outer)?;
32 let vis: syn::Visibility = input.parse()?;
33 let enum_token = input.parse::<syn::Token![enum]>()?;
34 let ident: syn::Ident = input.parse()?;
35 let generics: syn::Generics = input.parse()?;
36 let where_clause = input.parse()?;
37 let content;
38 let brace_token = syn::braced!(content in input);
39 let variants = content.parse_terminated(EnumDispatchVariant::parse, syn::Token![,])?;
40 Ok(Self {
41 attrs,
42 vis,
43 enum_token,
44 ident,
45 generics: syn::Generics {
46 where_clause,
47 ..generics
48 },
49 brace_token,
50 variants,
51 })
52 }
53}
54
55impl quote::ToTokens for EnumDispatchItem {
57 fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
58 tokens.append_all(self.attrs.outer());
59 self.vis.to_tokens(tokens);
60 self.enum_token.to_tokens(tokens);
61 self.ident.to_tokens(tokens);
62 self.generics.to_tokens(tokens);
63 self.generics.where_clause.to_tokens(tokens);
64 self.brace_token.surround(tokens, |tokens| {
65 self.variants.to_tokens(tokens);
66 });
67 }
68}
69
70impl ::std::convert::From<EnumDispatchItem> for syn::ItemEnum {
73 fn from(item: EnumDispatchItem) -> syn::ItemEnum {
74 use ::std::iter::FromIterator;
75 let variants: Vec<syn::Variant> = item
76 .variants
77 .iter()
78 .map(|variant: &EnumDispatchVariant| syn::Variant {
79 attrs: variant.attrs.to_owned(),
80 ident: variant.ident.to_owned(),
81 fields: syn::Fields::Unnamed(syn::FieldsUnnamed {
82 paren_token: Default::default(),
83 unnamed: {
84 let mut punctuated = syn::punctuated::Punctuated::new();
85 punctuated.push(syn::Field {
86 attrs: variant.field_attrs.to_owned(),
87 vis: syn::Visibility::Inherited,
88 ident: None,
89 colon_token: Default::default(),
90 ty: variant.ty.to_owned(),
91 mutability: syn::FieldMutability::None,
92 });
93 punctuated
94 },
95 }),
96 discriminant: None,
97 })
98 .collect();
99 syn::ItemEnum {
100 attrs: item.attrs,
101 vis: item.vis,
102 enum_token: item.enum_token,
103 ident: item.ident,
104 generics: syn::Generics {
105 where_clause: item.generics.where_clause,
106 ..item.generics
107 },
108 brace_token: item.brace_token,
109 variants: syn::punctuated::Punctuated::from_iter(variants),
110 }
111 }
112}