[−][src]Trait structural::field::IntoVariantField
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,
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>
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.
Provided methods
unsafe fn into_vfield_unchecked(
self,
variant_name: V,
field_name: F
) -> Self::Ty where
Self: Sized,
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
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.
Implementations on Foreign Types
impl<T> IntoVariantField<TStr<__TS<(__S, __o, __m, __e)>>, TStr<__TS<(__0,)>>> for Option<T>
[src]
fn into_vfield_(
self,
_: TStr<__TS<(__S, __o, __m, __e)>>,
_: TStr<__TS<(__0,)>>
) -> Option<T>
[src]
self,
_: TStr<__TS<(__S, __o, __m, __e)>>,
_: TStr<__TS<(__0,)>>
) -> Option<T>
fn box_into_vfield_(
self: Box<Self>,
vname: TStr<__TS<(__S, __o, __m, __e)>>,
fname: TStr<__TS<(__0,)>>
) -> Option<T>
[src]
self: Box<Self>,
vname: TStr<__TS<(__S, __o, __m, __e)>>,
fname: TStr<__TS<(__0,)>>
) -> Option<T>
impl<T, E> IntoVariantField<TStr<__TS<(__O, __k)>>, TStr<__TS<(__0,)>>> for Result<T, E>
[src]
fn into_vfield_(
self,
_: TStr<__TS<(__O, __k)>>,
_: TStr<__TS<(__0,)>>
) -> Option<T>
[src]
self,
_: TStr<__TS<(__O, __k)>>,
_: TStr<__TS<(__0,)>>
) -> Option<T>
fn box_into_vfield_(
self: Box<Self>,
vname: TStr<__TS<(__O, __k)>>,
fname: TStr<__TS<(__0,)>>
) -> Option<T>
[src]
self: Box<Self>,
vname: TStr<__TS<(__O, __k)>>,
fname: TStr<__TS<(__0,)>>
) -> Option<T>
impl<T, E> IntoVariantField<TStr<__TS<(__E, __r, __r)>>, TStr<__TS<(__0,)>>> for Result<T, E>
[src]
fn into_vfield_(
self,
_: TStr<__TS<(__E, __r, __r)>>,
_: TStr<__TS<(__0,)>>
) -> Option<E>
[src]
self,
_: TStr<__TS<(__E, __r, __r)>>,
_: TStr<__TS<(__0,)>>
) -> Option<E>
fn box_into_vfield_(
self: Box<Self>,
vname: TStr<__TS<(__E, __r, __r)>>,
fname: TStr<__TS<(__0,)>>
) -> Option<E>
[src]
self: Box<Self>,
vname: TStr<__TS<(__E, __r, __r)>>,
fname: TStr<__TS<(__0,)>>
) -> Option<E>
impl<T, __V, __F, __Ty> IntoVariantField<TStr<__V>, __F> for ManuallyDrop<T> where
T: Sized + IntoVariantField<TStr<__V>, __F, Ty = __Ty>,
[src]
T: Sized + IntoVariantField<TStr<__V>, __F, Ty = __Ty>,
fn into_vfield_(
self,
vname: TStr<__V>,
fname: __F
) -> Option<GetVariantFieldType<T, TStr<__V>, __F>>
[src]
self,
vname: TStr<__V>,
fname: __F
) -> Option<GetVariantFieldType<T, TStr<__V>, __F>>
fn box_into_vfield_(
self: Box<Self>,
vname: TStr<__V>,
fname: __F
) -> Option<GetVariantFieldType<T, TStr<__V>, __F>>
[src]
self: Box<Self>,
vname: TStr<__V>,
fname: __F
) -> Option<GetVariantFieldType<T, TStr<__V>, __F>>
impl<T: ?Sized, V, F, Ty> IntoVariantField<TStr<V>, F> for Box<T> where
T: IntoVariantField<TStr<V>, F, Ty = Ty>,
[src]
T: IntoVariantField<TStr<V>, F, Ty = Ty>,
fn into_vfield_(self, vname: TStr<V>, fname: F) -> Option<Ty>
[src]
fn box_into_vfield_(self: Box<Self>, vname: TStr<V>, fname: F) -> Option<Ty>
[src]
Implementors
impl<T, __V, __F, __Ty> IntoVariantField<TStr<__V>, __F> for StrucWrapper<T> where
T: Sized + IntoVariantField<TStr<__V>, __F, Ty = __Ty>,
[src]
T: Sized + IntoVariantField<TStr<__V>, __F, Ty = __Ty>,
fn into_vfield_(
self,
vname: TStr<__V>,
fname: __F
) -> Option<GetVariantFieldType<T, TStr<__V>, __F>>
[src]
self,
vname: TStr<__V>,
fname: __F
) -> Option<GetVariantFieldType<T, TStr<__V>, __F>>
fn box_into_vfield_(
self: Box<Self>,
vname: TStr<__V>,
fname: __F
) -> Option<GetVariantFieldType<T, TStr<__V>, __F>>
[src]
self: Box<Self>,
vname: TStr<__V>,
fname: __F
) -> Option<GetVariantFieldType<T, TStr<__V>, __F>>