Struct synstructure::Structure
[−]
[src]
pub struct Structure<'a> { /* fields omitted */ }
A wrapper around a syn::DeriveInput
which provides utilities for creating
custom derive trait implementations.
Methods
impl<'a> Structure<'a>
[src]
fn new(ast: &'a DeriveInput) -> Self
[src]
Create a new Structure
with the variants and fields from the passed-in
DeriveInput
.
fn variants(&self) -> &[VariantInfo<'a>]
[src]
Returns a slice of the variants in this Structure.
fn variants_mut(&mut self) -> &mut [VariantInfo<'a>]
[src]
Returns a mut slice of the variants in this Structure.
fn ast(&self) -> &'a DeriveInput
[src]
Returns a reference to the underlying syn
AST node which this
Structure
was created from.
fn omitted_variants(&self) -> bool
[src]
True if any variants were omitted due to a filter_variants
call.
fn each<F, R>(&self, f: F) -> Tokens where
F: FnMut(&BindingInfo) -> R,
R: ToTokens,
[src]
F: FnMut(&BindingInfo) -> R,
R: ToTokens,
Runs the passed-in function once for each bound field, passing in a BindingInfo
.
and generating match
arms which evaluate the returned tokens.
This method will ignore variants or fields which are ignored through the
filter
and filter_variant
methods.
Example
let di: syn::DeriveInput = parse_quote! { enum A { B(i32, i32), C(u32), } }; let s = Structure::new(&di); assert_eq!( s.each(|bi| quote!(println!("{:?}", #bi))), quote!{ A::B(ref __binding_0, ref __binding_1,) => { { println!("{:?}", __binding_0) } { println!("{:?}", __binding_1) } } A::C(ref __binding_0,) => { { println!("{:?}", __binding_0) } } } );
fn fold<F, I, R>(&self, init: I, f: F) -> Tokens where
F: FnMut(Tokens, &BindingInfo) -> R,
I: ToTokens,
R: ToTokens,
[src]
F: FnMut(Tokens, &BindingInfo) -> R,
I: ToTokens,
R: ToTokens,
Runs the passed-in function once for each bound field, passing in the
result of the previous call, and a BindingInfo
. generating match
arms which evaluate to the resulting tokens.
This method will ignore variants or fields which are ignored through the
filter
and filter_variant
methods.
If a variant has been ignored, it will return the init
value.
Example
let di: syn::DeriveInput = parse_quote! { enum A { B(i32, i32), C(u32), } }; let s = Structure::new(&di); assert_eq!( s.fold(quote!(0), |acc, bi| quote!(#acc + #bi)), quote!{ A::B(ref __binding_0, ref __binding_1,) => { 0 + __binding_0 + __binding_1 } A::C(ref __binding_0,) => { 0 + __binding_0 } } );
fn each_variant<F, R>(&self, f: F) -> Tokens where
F: FnMut(&VariantInfo) -> R,
R: ToTokens,
[src]
F: FnMut(&VariantInfo) -> R,
R: ToTokens,
Runs the passed-in function once for each variant, passing in a
VariantInfo
. and generating match
arms which evaluate the returned
tokens.
This method will ignore variants and not bind fields which are ignored
through the filter
and filter_variant
methods.
Example
let di: syn::DeriveInput = parse_quote! { enum A { B(i32, i32), C(u32), } }; let s = Structure::new(&di); assert_eq!( s.each_variant(|v| { let name = &v.ast().ident; quote!(println!(stringify!(#name))) }), quote!{ A::B(ref __binding_0, ref __binding_1,) => { println!(stringify!(B)) } A::C(ref __binding_0,) => { println!(stringify!(C)) } } );
fn filter<F>(&mut self, f: F) -> &mut Self where
F: FnMut(&BindingInfo) -> bool,
[src]
F: FnMut(&BindingInfo) -> bool,
Filter the bindings created by this Structure
object. This has 2 effects:
The bindings will no longer appear in match arms generated by methods on this
Structure
or its subobjects.Impl blocks created with the
bound_impl
orunsafe_bound_impl
method only consider type parameters referenced in the types of non-filtered fields.
Example
let di: syn::DeriveInput = parse_quote! { enum A { B{ a: i32, b: i32 }, C{ a: u32 }, } }; let mut s = Structure::new(&di); s.filter(|bi| { bi.ast().ident == Some("a".into()) }); assert_eq!( s.each(|bi| quote!(println!("{:?}", #bi))), quote!{ A::B{ a: ref __binding_0, .. } => { { println!("{:?}", __binding_0) } } A::C{ a: ref __binding_0, } => { { println!("{:?}", __binding_0) } } } );
fn filter_variants<F>(&mut self, f: F) -> &mut Self where
F: FnMut(&VariantInfo) -> bool,
[src]
F: FnMut(&VariantInfo) -> bool,
Filter the variants matched by this Structure
object. This has 2 effects:
Match arms destructuring these variants will no longer be generated by methods on this
Structure
Impl blocks created with the
bound_impl
orunsafe_bound_impl
method only consider type parameters referenced in the types of fields in non-fitered variants.
Example
let di: syn::DeriveInput = parse_quote! { enum A { B(i32, i32), C(u32), } }; let mut s = Structure::new(&di); s.filter_variants(|v| v.ast().ident != "B"); assert_eq!( s.each(|bi| quote!(println!("{:?}", #bi))), quote!{ A::C(ref __binding_0,) => { { println!("{:?}", __binding_0) } } _ => {} } );
fn remove_variant(&mut self, idx: usize) -> &mut Self
[src]
fn bind_with<F>(&mut self, f: F) -> &mut Self where
F: FnMut(&BindingInfo) -> BindStyle,
[src]
F: FnMut(&BindingInfo) -> BindStyle,
Updates the BindStyle
for each of the passed-in fields by calling the
passed-in function for each BindingInfo
.
Example
let di: syn::DeriveInput = parse_quote! { enum A { B(i32, i32), C(u32), } }; let mut s = Structure::new(&di); s.bind_with(|bi| BindStyle::RefMut); assert_eq!( s.each(|bi| quote!(println!("{:?}", #bi))), quote!{ A::B(ref mut __binding_0, ref mut __binding_1,) => { { println!("{:?}", __binding_0) } { println!("{:?}", __binding_1) } } A::C(ref mut __binding_0,) => { { println!("{:?}", __binding_0) } } } );
fn binding_name<F>(&mut self, f: F) -> &mut Self where
F: FnMut(&Field, usize) -> Ident,
[src]
F: FnMut(&Field, usize) -> Ident,
Updates the binding name for each fo the passed-in fields by calling the
passed-in function for each BindingInfo
.
The function will be called with the BindingInfo
and its index in the
enclosing variant.
The default name is __binding_{}
where {}
is replaced with an
increasing number.
Example
let di: syn::DeriveInput = parse_quote! { enum A { B{ a: i32, b: i32 }, C{ a: u32 }, } }; let mut s = Structure::new(&di); s.binding_name(|bi, i| bi.ident.clone().unwrap()); assert_eq!( s.each(|bi| quote!(println!("{:?}", #bi))), quote!{ A::B{ a: ref a, b: ref b, } => { { println!("{:?}", a) } { println!("{:?}", b) } } A::C{ a: ref a, } => { { println!("{:?}", a) } } } );
fn referenced_ty_params(&self) -> Vec<&'a Ident>
[src]
Returns a list of the type parameters which are refrenced in the types of non-filtered fields / variants.
Caveat
If the struct contains any macros in type position, all parameters will be considered bound. This is because we cannot determine which type parameters are bound by type macros.
Example
let di: syn::DeriveInput = parse_quote! { enum A<T, U> { B(T, i32), C(Option<U>), } }; let mut s = Structure::new(&di); s.filter_variants(|v| v.ast().ident != "C"); assert_eq!( s.referenced_ty_params(), &[&(syn::Ident::from("T"))] );
fn add_trait_bounds(
&self,
bound: &TraitBound,
where_clause: &mut Option<WhereClause>
)
[src]
&self,
bound: &TraitBound,
where_clause: &mut Option<WhereClause>
)
Add trait bounds for a trait with the given path for each type parmaeter referenced in the types of non-filtered fields.
Caveat
If the method contains any macros in type position, all parameters will be considered bound. This is because we cannot determine which type parameters are bound by type macros.
fn bound_impl<P: ToTokens, B: ToTokens>(&self, path: P, body: B) -> Tokens
[src]
Creates an impl
block with the required generic type fields filled in
to implement the trait path
.
This method also adds where clauses to the impl requiring that all
referenced type parmaeters implement the trait path
.
Hygiene and Paths
This method wraps the impl block inside of a const
(see the example
below). In this scope, the first segment of the passed-in path is
extern crate
-ed in. If you don't want to generate that extern crate
item, use a global path.
This means that if you are implementing my_crate::Trait
, you simply
write s.bound_impl(quote!(my_crate::Trait), quote!(...))
, and for the
entirety of the definition, you can refer to your crate as my_crate
.
Caveat
If the method contains any macros in type position, all parameters will be considered bound. This is because we cannot determine which type parameters are bound by type macros.
Panics
Panics if the path string parameter is not a valid TraitBound
.
Example
let di: syn::DeriveInput = parse_quote! { enum A<T, U> { B(T), C(Option<U>), } }; let mut s = Structure::new(&di); s.filter_variants(|v| v.ast().ident != "B"); assert_eq!( s.bound_impl(quote!(krate::Trait), quote!{ fn a() {} }), quote!{ #[allow(non_upper_case_globals)] const _DERIVE_krate_Trait_FOR_A: () = { extern crate krate; impl<T, U> krate::Trait for A<T, U> where Option<U>: krate::Trait, U: krate::Trait { fn a() {} } }; } );
fn unsafe_bound_impl<P: ToTokens, B: ToTokens>(
&self,
path: P,
body: B
) -> Tokens
[src]
&self,
path: P,
body: B
) -> Tokens
Creates an impl
block with the required generic type fields filled in
to implement the unsafe trait path
.
This method also adds where clauses to the impl requiring that all
referenced type parmaeters implement the trait path
.
Hygiene and Paths
This method wraps the impl block inside of a const
(see the example
below). In this scope, the first segment of the passed-in path is
extern crate
-ed in. If you don't want to generate that extern crate
item, use a global path.
This means that if you are implementing my_crate::Trait
, you simply
write s.bound_impl(quote!(my_crate::Trait), quote!(...))
, and for the
entirety of the definition, you can refer to your crate as my_crate
.
Caveat
If the method contains any macros in type position, all parameters will be considered bound. This is because we cannot determine which type parameters are bound by type macros.
Panics
Panics if the path string parameter is not a valid TraitBound
.
Example
let di: syn::DeriveInput = parse_quote! { enum A<T, U> { B(T), C(Option<U>), } }; let mut s = Structure::new(&di); s.filter_variants(|v| v.ast().ident != "B"); assert_eq!( s.unsafe_bound_impl(quote!(krate::Trait), quote!{ fn a() {} }), quote!{ #[allow(non_upper_case_globals)] const _DERIVE_krate_Trait_FOR_A: () = { extern crate krate; unsafe impl<T, U> krate::Trait for A<T, U> where Option<U>: krate::Trait, U: krate::Trait { fn a() {} } }; } );
fn unbound_impl<P: ToTokens, B: ToTokens>(&self, path: P, body: B) -> Tokens
[src]
Creates an impl
block with the required generic type fields filled in
to implement the trait path
.
This method will not add any where clauses to the impl.
Hygiene and Paths
This method wraps the impl block inside of a const
(see the example
below). In this scope, the first segment of the passed-in path is
extern crate
-ed in. If you don't want to generate that extern crate
item, use a global path.
This means that if you are implementing my_crate::Trait
, you simply
write s.bound_impl(quote!(my_crate::Trait), quote!(...))
, and for the
entirety of the definition, you can refer to your crate as my_crate
.
Panics
Panics if the path string parameter is not a valid TraitBound
.
Example
let di: syn::DeriveInput = parse_quote! { enum A<T, U> { B(T), C(Option<U>), } }; let mut s = Structure::new(&di); s.filter_variants(|v| v.ast().ident != "B"); assert_eq!( s.unbound_impl(quote!(krate::Trait), quote!{ fn a() {} }), quote!{ #[allow(non_upper_case_globals)] const _DERIVE_krate_Trait_FOR_A: () = { extern crate krate; impl<T, U> krate::Trait for A<T, U> { fn a() {} } }; } );
fn unsafe_unbound_impl<P: ToTokens, B: ToTokens>(
&self,
path: P,
body: B
) -> Tokens
[src]
&self,
path: P,
body: B
) -> Tokens
Creates an impl
block with the required generic type fields filled in
to implement the unsafe trait path
.
This method will not add any where clauses to the impl.
Hygiene and Paths
This method wraps the impl block inside of a const
(see the example
below). In this scope, the first segment of the passed-in path is
extern crate
-ed in. If you don't want to generate that extern crate
item, use a global path.
This means that if you are implementing my_crate::Trait
, you simply
write s.bound_impl(quote!(my_crate::Trait), quote!(...))
, and for the
entirety of the definition, you can refer to your crate as my_crate
.
Panics
Panics if the path string parameter is not a valid TraitBound
.
Example
let di: syn::DeriveInput = parse_quote! { enum A<T, U> { B(T), C(Option<U>), } }; let mut s = Structure::new(&di); s.filter_variants(|v| v.ast().ident != "B"); assert_eq!( s.unsafe_unbound_impl(quote!(krate::Trait), quote!{ fn a() {} }), quote!{ #[allow(non_upper_case_globals)] const _DERIVE_krate_Trait_FOR_A: () = { extern crate krate; unsafe impl<T, U> krate::Trait for A<T, U> { fn a() {} } }; } );
Trait Implementations
impl<'a> Debug for Structure<'a>
[src]
impl<'a> Clone for Structure<'a>
[src]
fn clone(&self) -> Structure<'a>
[src]
Returns a copy of the value. Read more
fn clone_from(&mut self, source: &Self)
1.0.0[src]
Performs copy-assignment from source
. Read more
impl<'a> PartialEq for Structure<'a>
[src]
fn eq(&self, __arg_0: &Structure<'a>) -> bool
[src]
This method tests for self
and other
values to be equal, and is used by ==
. Read more
fn ne(&self, __arg_0: &Structure<'a>) -> bool
[src]
This method tests for !=
.