[][src]Trait structural::field::IntoVariantField

pub unsafe trait IntoVariantField<V, F>: GetVariantField<V, F> {
    fn into_vfield_(self, variant_name: V, field_name: F) -> Option<Self::Ty>
    where
        Self: Sized
;
fn box_into_vfield_(
        self: Box<Self>,
        variant_name: V,
        field_name: F
    ) -> Option<Self::Ty>; unsafe fn into_vfield_unchecked(
        self,
        variant_name: V,
        field_name: F
    ) -> Self::Ty
    where
        Self: Sized
, { ... }
unsafe fn box_into_vfield_unchecked(
        self: Box<Self>,
        variant_name: V,
        field_name: F
    ) -> Self::Ty { ... } }

Provides shared and by-value 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 IntoVariantField<V, F> must agree on what variant the enum currently is. If IsVariant returns true for a particular V variant, then into_vfield_,and box_into_vfield_ must return Some(_).

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.

Features

If you disable the default feature,and don't enable the "alloc" feature, you must implement the box_into_vfield_ method using the z_impl_box_into_variant_field_method macro, this trait's manual implementation example shows how you can use the macro.

Example

use structural::field::IntoVariantField;
use structural::for_examples::{Bomb,WithBoom};
use structural::{StructuralExt,TS,fp};

fn example<T>(mut this: T)
where
    T: IntoVariantField<TS!(Boom),TS!(a),Ty= &'static str>+
       IntoVariantField<TS!(Boom),TS!(b),Ty= &'static [u16]>,
{
    assert_eq!( this.is_variant(fp!(Boom)), true );

    assert_eq!( this.field_(fp!(::Boom.a)), Some(&"Because.") );

    assert_eq!( this.cloned_fields(fp!(::Boom=>a,b)), Some(( "Because.", &[13,21][..] )) );

    assert_eq!( this.fields(fp!(::Boom=>a,b)), Some(( &"Because.", &&[13,21][..] )) );

    assert_eq!( this.into_field(fp!(::Boom.a)), Some("Because.") );
}

example(WithBoom::Boom{ a:"Because.", b:&[13,21] });
example(Bomb::Boom{ a:"Because.", b:&[13,21] });

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, IntoVariantField, FP, TS,
    StructuralExt,fp,structural_alias,
};
use structural::enums::{IsVariant, VariantCount};

// The `FooBounds` trait is defined below.
fn using_enum(bar: impl FooBounds, baz: impl FooBounds){
    assert_eq!( bar.fields(fp!(::Bar=>0,1)), Some((&34, &51)) );
    assert_eq!( bar.into_field(fp!(::Bar.0)), Some(34) );
    assert_eq!( bar.into_field(fp!(::Bar.1)), Some(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.into_field(fp!(::Bar.0)), None );
    assert_eq!( baz.into_field(fp!(::Bar.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);


#[derive(Copy,Clone)]
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,
        }
    }
}

unsafe impl IntoVariantField<TS!(Bar),TS!(0)> for Foo{
    fn into_vfield_(self, _:TS!(Bar), _:TS!(0)) -> Option<u32>{
        match self {
            Foo::Bar(ret,_)=>Some(ret),
            _=>None,
        }
    }
     
    // You must use this, even in crates that don't enable the "alloc" feature
    // (the "alloc" feature is enabled by default),
    // since other crates that depend on structural might enable the feature.
    structural::z_impl_box_into_variant_field_method!{
        variant_tstr= TS!(Bar),
        field_tstr= TS!(0),
        field_type= u32,
    }
}


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 IntoVariantField<TS!(Bar),TS!(1)> for Foo{
    fn into_vfield_(self, _:TS!(Bar), _:TS!(1)) -> Option<u64>{
        match self {
            Foo::Bar(_,ret)=>Some(ret),
            _=>None,
        }
    }
     
    structural::z_impl_box_into_variant_field_method!{
        variant_tstr= TS!(Bar),
        field_tstr= TS!(1),
        field_type= u64,
    }
}


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

structural_alias!{
    trait FooBounds: Copy{
        move Bar(u32,u64),
        move Baz,
    }
}

Required methods

fn into_vfield_(self, variant_name: V, field_name: F) -> Option<Self::Ty> where
    Self: Sized

Converts this into the F field in the V variant by value.

fn box_into_vfield_(
    self: Box<Self>,
    variant_name: V,
    field_name: F
) -> Option<Self::Ty>

Converts this into the F field in the V variant by value.

This method exists so that Box<dyn Trait> can be converted into a field by value.

Loading content...

Provided methods

unsafe fn into_vfield_unchecked(
    self,
    variant_name: V,
    field_name: F
) -> Self::Ty where
    Self: Sized

Converts this into the F field in the V variant by value, without checking that the enum is currently the V variant.

Safety

The enum must be the V variant.

unsafe fn box_into_vfield_unchecked(
    self: Box<Self>,
    variant_name: V,
    field_name: F
) -> Self::Ty

Converts this into the F field in the V variant by value, without checking that the enum is currently the V variant.

This method exists so that Box<dyn Trait> can be converted into a field by value.

Safety

The enum must be the V variant.

Features

This method is defined conditional on the "alloc" feature, read here for more details.

Loading content...

Implementations on Foreign Types

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

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

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

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

impl<T: ?Sized, V, F, Ty> IntoVariantField<TStr<V>, F> for Box<T> where
    T: IntoVariantField<TStr<V>, F, Ty = Ty>, 
[src]

Loading content...

Implementors

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

Loading content...