synstructure

Struct VariantInfo

Source
pub struct VariantInfo<'a> {
    pub prefix: Option<&'a Ident>,
    /* private fields */
}
Expand description

A wrapper around a syn::DeriveInput’s variant which provides utilities for destructuring Variants with match expressions.

Fields§

§prefix: Option<&'a Ident>

Implementations§

Source§

impl<'a> VariantInfo<'a>

Source

pub fn bindings(&self) -> &[BindingInfo<'a>]

Returns a slice of the bindings in this Variant.

Source

pub fn bindings_mut(&mut self) -> &mut [BindingInfo<'a>]

Returns a mut slice of the bindings in this Variant.

Source

pub fn ast(&self) -> VariantAst<'a>

Returns a VariantAst object which contains references to the underlying syn AST node which this Variant was created from.

Source

pub fn omitted_bindings(&self) -> bool

True if any bindings were omitted due to a filter call.

Source

pub fn pat(&self) -> TokenStream

Generates the match-arm pattern which could be used to match against this Variant.

§Example
let di: syn::DeriveInput = syn::parse_quote! {
    enum A {
        B(i32, i32),
        C(u32),
    }
};
let s = Structure::new(&di);

assert_eq!(
    s.variants()[0].pat().to_string(),
    quote!{
        A::B(ref __binding_0, ref __binding_1,)
    }.to_string()
);
Source

pub fn construct<F, T>(&self, func: F) -> TokenStream
where F: FnMut(&Field, usize) -> T, T: ToTokens,

Generates the token stream required to construct the current variant.

The init array initializes each of the fields in the order they are written in variant.ast().fields.

§Example
let di: syn::DeriveInput = syn::parse_quote! {
    enum A {
        B(usize, usize),
        C{ v: usize },
    }
};
let s = Structure::new(&di);

assert_eq!(
    s.variants()[0].construct(|_, i| quote!(#i)).to_string(),

    quote!{
        A::B(0usize, 1usize,)
    }.to_string()
);

assert_eq!(
    s.variants()[1].construct(|_, i| quote!(#i)).to_string(),

    quote!{
        A::C{ v: 0usize, }
    }.to_string()
);
Source

pub fn each<F, R>(&self, f: F) -> TokenStream
where F: FnMut(&BindingInfo<'_>) -> R, R: ToTokens,

Runs the passed-in function once for each bound field, passing in a BindingInfo. and generating a match arm which evaluates the returned tokens.

This method will ignore fields which are ignored through the filter method.

§Example
let di: syn::DeriveInput = syn::parse_quote! {
    enum A {
        B(i32, i32),
        C(u32),
    }
};
let s = Structure::new(&di);

assert_eq!(
    s.variants()[0].each(|bi| quote!(println!("{:?}", #bi))).to_string(),

    quote!{
        A::B(ref __binding_0, ref __binding_1,) => {
            { println!("{:?}", __binding_0) }
            { println!("{:?}", __binding_1) }
        }
    }.to_string()
);
Source

pub fn fold<F, I, R>(&self, init: I, f: F) -> TokenStream
where F: FnMut(TokenStream, &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 a match arm which evaluates to the resulting tokens.

This method will ignore fields which are ignored through the filter method.

§Example
let di: syn::DeriveInput = syn::parse_quote! {
    enum A {
        B(i32, i32),
        C(u32),
    }
};
let s = Structure::new(&di);

assert_eq!(
    s.variants()[0].fold(quote!(0), |acc, bi| quote!(#acc + #bi)).to_string(),

    quote!{
        A::B(ref __binding_0, ref __binding_1,) => {
            0 + __binding_0 + __binding_1
        }
    }.to_string()
);
Source

pub fn filter<F>(&mut self, f: F) -> &mut Self
where F: FnMut(&BindingInfo<'_>) -> bool,

Filter the bindings created by this Variant object. This has 2 effects:

  • The bindings will no longer appear in match arms generated by methods on this Variant or its subobjects.

  • Impl blocks created with the bound_impl or unsafe_bound_impl method only consider type parameters referenced in the types of non-filtered fields.

§Example
let di: syn::DeriveInput = syn::parse_quote! {
    enum A {
        B{ a: i32, b: i32 },
        C{ a: u32 },
    }
};
let mut s = Structure::new(&di);

s.variants_mut()[0].filter(|bi| {
    bi.ast().ident == Some(quote::format_ident!("b"))
});

assert_eq!(
    s.each(|bi| quote!(println!("{:?}", #bi))).to_string(),

    quote!{
        A::B{ b: ref __binding_1, .. } => {
            { println!("{:?}", __binding_1) }
        }
        A::C{ a: ref __binding_0, } => {
            { println!("{:?}", __binding_0) }
        }
    }.to_string()
);
Source

pub fn drain_filter<F>(&mut self, f: F) -> Self
where F: FnMut(&BindingInfo<'_>) -> bool,

Iterates all the bindings of this Variant object and uses a closure to determine if a binding should be removed. If the closure returns true the binding is removed from the variant. If the closure returns false, the binding remains in the variant.

All the removed bindings are moved to a new Variant object which is otherwise identical to the current one. To understand the effects of removing a binding from a variant check the VariantInfo::filter documentation.

§Example
let di: syn::DeriveInput = syn::parse_quote! {
    enum A {
        B{ a: i32, b: i32 },
        C{ a: u32 },
    }
};
let mut s = Structure::new(&di);

let mut with_b = &mut s.variants_mut()[0];

let with_a = with_b.drain_filter(|bi| {
    bi.ast().ident == Some(quote::format_ident!("a"))
});

assert_eq!(
    with_a.each(|bi| quote!(println!("{:?}", #bi))).to_string(),

    quote!{
        A::B{ a: ref __binding_0, .. } => {
            { println!("{:?}", __binding_0) }
        }
    }.to_string()
);

assert_eq!(
    with_b.each(|bi| quote!(println!("{:?}", #bi))).to_string(),

    quote!{
        A::B{ b: ref __binding_1, .. } => {
            { println!("{:?}", __binding_1) }
        }
    }.to_string()
);
Source

pub fn remove_binding(&mut self, idx: usize) -> &mut Self

Remove the binding at the given index.

§Panics

Panics if the index is out of range.

Source

pub fn bind_with<F>(&mut self, f: F) -> &mut Self
where 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 = syn::parse_quote! {
    enum A {
        B(i32, i32),
        C(u32),
    }
};
let mut s = Structure::new(&di);

s.variants_mut()[0].bind_with(|bi| BindStyle::RefMut);

assert_eq!(
    s.each(|bi| quote!(println!("{:?}", #bi))).to_string(),

    quote!{
        A::B(ref mut __binding_0, ref mut __binding_1,) => {
            { println!("{:?}", __binding_0) }
            { println!("{:?}", __binding_1) }
        }
        A::C(ref __binding_0,) => {
            { println!("{:?}", __binding_0) }
        }
    }.to_string()
);
Source

pub fn binding_name<F>(&mut self, f: F) -> &mut Self
where 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 = syn::parse_quote! {
    enum A {
        B{ a: i32, b: i32 },
        C{ a: u32 },
    }
};
let mut s = Structure::new(&di);

s.variants_mut()[0].binding_name(|bi, i| bi.ident.clone().unwrap());

assert_eq!(
    s.each(|bi| quote!(println!("{:?}", #bi))).to_string(),

    quote!{
        A::B{ a: ref a, b: ref b, } => {
            { println!("{:?}", a) }
            { println!("{:?}", b) }
        }
        A::C{ a: ref __binding_0, } => {
            { println!("{:?}", __binding_0) }
        }
    }.to_string()
);
Source

pub fn referenced_ty_params(&self) -> Vec<&'a Ident>

Returns a list of the type parameters which are referenced in this field’s type.

§Caveat

If the field 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 = syn::parse_quote! {
    struct A<T, U> {
        a: Option<T>,
        b: U,
    }
};
let mut s = Structure::new(&di);

assert_eq!(
    s.variants()[0].bindings()[0].referenced_ty_params(),
    &[&quote::format_ident!("T")]
);

Trait Implementations§

Source§

impl<'a> Clone for VariantInfo<'a>

Source§

fn clone(&self) -> VariantInfo<'a>

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a> Debug for VariantInfo<'a>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'a> Hash for VariantInfo<'a>

Source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl<'a> PartialEq for VariantInfo<'a>

Source§

fn eq(&self, other: &VariantInfo<'a>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<'a> Eq for VariantInfo<'a>

Source§

impl<'a> StructuralPartialEq for VariantInfo<'a>

Auto Trait Implementations§

§

impl<'a> Freeze for VariantInfo<'a>

§

impl<'a> RefUnwindSafe for VariantInfo<'a>

§

impl<'a> !Send for VariantInfo<'a>

§

impl<'a> !Sync for VariantInfo<'a>

§

impl<'a> Unpin for VariantInfo<'a>

§

impl<'a> UnwindSafe for VariantInfo<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dst: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.