1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
use syn; use quote::ToTokens; use proc_macro2::TokenStream as TokenStream2; use field::{Field, FieldParent, Fields}; #[derive(Debug)] pub struct Derived<'p, T: 'p> { pub derive_input: &'p syn::DeriveInput, pub value: &'p T, } pub type Variant<'v> = Derived<'v, syn::Variant>; pub type Struct<'v> = Derived<'v, syn::DataStruct>; pub type Enum<'v> = Derived<'v, syn::DataEnum>; impl<'p, T> Derived<'p, T> { pub fn from(derive_input: &'p syn::DeriveInput, value: &'p T) -> Self { Derived { derive_input, value } } } impl<'p, T> ::std::ops::Deref for Derived<'p, T> { type Target = T; fn deref(&self) -> &T { self.value } } impl<'p, T: ToTokens> ToTokens for Derived<'p, T> { fn to_tokens(&self, tokens: &mut TokenStream2) { self.value.to_tokens(tokens) } } impl<'p, T> Copy for Derived<'p, T> { } impl<'p, T> Clone for Derived<'p, T> { fn clone(&self) -> Derived<'p, T> { *self } } impl<'f> Variant<'f> { pub fn builder<F: Fn(Field) -> TokenStream2>(&self, f: F) -> TokenStream2 { let variant = &self.ident; let expression = self.fields().iter().map(f); let enum_name = &self.derive_input.ident; if self.fields().are_named() { let field_name = self.fields.iter().map(|f| f.ident.as_ref().unwrap()); quote! { #enum_name::#variant { #(#field_name: #expression),* } } } else if self.fields().are_unnamed() { quote! { #enum_name::#variant(#(#expression),*) } } else { quote! { #enum_name::#variant } } } pub fn fields(self) -> Fields<'f> { FieldParent::Variant(self).fields() } } impl<'p> Enum<'p> { pub fn variants(self) -> impl Iterator<Item = Variant<'p>> { self.value.variants.iter() .map(move |v| Derived::from(&self.derive_input, v)) } } impl<'p> Struct<'p> { pub fn fields(self) -> Fields<'p> { FieldParent::Struct(self).fields() } }