[][src]Trait structural::field::GetVariantField

pub unsafe trait GetVariantField<V, F>: IsVariant<V> + FieldType<VariantField<V, F>> {
    fn get_vfield_(&self, variant: V, field: F) -> Option<&Self::Ty>;

    unsafe fn get_vfield_unchecked(&self, variant: V, field: F) -> &Self::Ty { ... }
}

Provides shared access to an enum variant field.

The V and F type parameters are expected to be TStr.

Every instance of "the F field"/"the V variant" in the docs mean "in the field/variant named by the F/V type parameter"

Safety

IsVariant<V> and GetVariantField<V, F> must agree on what variant the enum currently is. If IsVariant returns true for a particular V variant, then get_vfield_ must return Some(_) for the same variant.

If overriden, the *_unchecked methods must diverge (abort, panic, or call the equivalent of std::hint::unreachable_unchecked) if the enum is not currently the V variant, and return the same field as the checked equivalents if the enum is currently the V variant.

Example: Use as bound

use structural::field::GetVariantField;
use structural::for_examples::{Variants,WithBar};
use structural::{StructuralExt,TS,fp};

fn example(this: impl GetVariantField<TS!(Bar),TS!(0),Ty= &'static str>){
    assert_eq!( this.field_(fp!(::Bar.0)), Some(&"why?") );

    // You can use `fp!(::Foo=>bar,baz)` to access multiple fields inside
    // an enum variant.
    assert_eq!( this.fields(fp!(::Bar=>0,0)), Some((&"why?",&"why?")) );

    assert_eq!( this.cloned_fields(fp!(::Bar=>0,0)), Some(("why?","why?")) );

    assert_eq!( this.is_variant(fp!(Bar)), true );
}

example(Variants::Bar("why?"));
example(WithBar::Bar("why?"));

Example: Manual implementation

While this trait is better derived, it can be implemented manually.

Note that the derive macro also declares trait aliases for the traits implemented here.

use structural::{
    FieldType, GetVariantField, FP, TS,
    StructuralExt,fp,structural_alias,
};
use structural::enums::{IsVariant, VariantCount};

// The `FooBounds` trait is defined below.
fn using_enum(bar: &dyn FooBounds, baz: &dyn FooBounds){
    assert_eq!( bar.fields(fp!(::Bar=>0,1)), Some((&34, &51)) );
    assert_eq!( bar.is_variant(fp!(Bar)), true );
    assert_eq!( bar.is_variant(fp!(Baz)), false );

    assert_eq!( baz.fields(fp!(::Bar=>0,1)), None );
    assert_eq!( baz.is_variant(fp!(Bar)), false );
    assert_eq!( baz.is_variant(fp!(Baz)), true );
}


using_enum(&Foo::Bar(34,51), &Foo::Baz);


enum Foo{
    Bar(u32,u64),
    Baz,
}

unsafe impl VariantCount for Foo{
    type Count=TS!(2);
}

unsafe impl IsVariant<TS!(Bar)> for Foo {
    fn is_variant_(&self,_:TS!(Bar))->bool{
        match self {
            Foo::Bar{..}=>true,
            _=>false,
        }
    }
}

impl FieldType<FP!(::Bar.0)> for Foo{
    type Ty=u32;
}

unsafe impl GetVariantField<TS!(Bar),TS!(0)> for Foo{
    fn get_vfield_(&self, _:TS!(Bar), _:TS!(0)) -> Option<&u32>{
        match self {
            Foo::Bar(ret,_)=>Some(ret),
            _=>None,
        }
    }
}


impl FieldType<FP!(::Bar.1)> for Foo{
    type Ty=u64;
}

unsafe impl GetVariantField<TS!(Bar),TS!(1)> for Foo{
    fn get_vfield_(&self, _:TS!(Bar), _:TS!(1)) -> Option<&u64>{
        match self {
            Foo::Bar(_,ret)=>Some(ret),
            _=>None,
        }
    }
}


unsafe impl IsVariant<TS!(Baz)> for Foo {
    fn is_variant_(&self,_:TS!(Baz))->bool{
        match self {
            Foo::Baz{..}=>true,
            _=>false,
        }
    }
}

structural_alias!{
    trait FooBounds{
        ref Bar(u32,u64),
        ref Baz,
    }
}

Required methods

fn get_vfield_(&self, variant: V, field: F) -> Option<&Self::Ty>

Accesses the F field in the V variant by reference.

Loading content...

Provided methods

unsafe fn get_vfield_unchecked(&self, variant: V, field: F) -> &Self::Ty

Accesses the F field in the V variant by reference, without checking that the enum is currently the V variant.

Safety

The enum must be the V variant.

Loading content...

Implementations on Foreign Types

impl<T> GetVariantField<TStr<__TS<(__S, __o, __m, __e)>>, TStr<__TS<(__0,)>>> for Option<T>[src]

impl<T, E> GetVariantField<TStr<__TS<(__O, __k)>>, TStr<__TS<(__0,)>>> for Result<T, E>[src]

impl<T, E> GetVariantField<TStr<__TS<(__E, __r, __r)>>, TStr<__TS<(__0,)>>> for Result<T, E>[src]

impl<T, __V, __F, __Ty> GetVariantField<TStr<__V>, __F> for ManuallyDrop<T> where
    T: GetVariantField<TStr<__V>, __F, Ty = __Ty>, 
[src]

impl<P, __V, __F, __Ty> GetVariantField<TStr<__V>, __F> for Pin<P> where
    P::Target: GetVariantField<TStr<__V>, __F, Ty = __Ty>,
    P: Deref,
    P::Target: Sized
[src]

impl<T, __V, __F, __Ty> GetVariantField<TStr<__V>, __F> for Arc<T> where
    T: GetVariantField<TStr<__V>, __F, Ty = __Ty>,
    T: ?Sized
[src]

impl<T, __V, __F, __Ty> GetVariantField<TStr<__V>, __F> for Rc<T> where
    T: GetVariantField<TStr<__V>, __F, Ty = __Ty>,
    T: ?Sized
[src]

impl<T, __V, __F, __Ty> GetVariantField<TStr<__V>, __F> for Box<T> where
    T: GetVariantField<TStr<__V>, __F, Ty = __Ty>,
    T: ?Sized
[src]

impl<'a, T, __V, __F, __Ty> GetVariantField<TStr<__V>, __F> for &'a T where
    T: GetVariantField<TStr<__V>, __F, Ty = __Ty>,
    T: ?Sized
[src]

impl<'a, T, __V, __F, __Ty> GetVariantField<TStr<__V>, __F> for &'a mut T where
    T: GetVariantField<TStr<__V>, __F, Ty = __Ty>,
    T: 'a + ?Sized
[src]

Loading content...

Implementors

impl<T, __V, __F, __Ty> GetVariantField<TStr<__V>, __F> for FieldCloner<T> where
    T: GetVariantField<TStr<__V>, __F, Ty = __Ty>, 
[src]

impl<T, __V, __F, __Ty> GetVariantField<TStr<__V>, __F> for StrucWrapper<T> where
    T: GetVariantField<TStr<__V>, __F, Ty = __Ty>, 
[src]

Loading content...