[][src]Trait structural::field::GetVariantFieldMut

pub unsafe trait GetVariantFieldMut<V, F>: GetVariantField<V, F> {
    fn get_vfield_mut_(&mut self, variant: V, field: F) -> Option<&mut Self::Ty>;
unsafe fn get_vfield_raw_mut_(
        ptr: *mut (),
        variant: V,
        field: F
    ) -> Option<NonNull<Self::Ty>>
    where
        Self: Sized
;
fn get_vfield_raw_mut_fn(&self) -> GetVFieldRawMutFn<V, F, Self::Ty>;
fn get_vfield_raw_mut_unchecked_fn(&self) -> GetFieldRawMutFn<F, Self::Ty>; unsafe fn get_vfield_mut_unchecked(
        &mut self,
        variant: V,
        field: F
    ) -> &mut Self::Ty { ... }
unsafe fn get_vfield_raw_mut_unchecked(
        ptr: *mut (),
        field: F
    ) -> *mut Self::Ty
    where
        Self: Sized,
        V: ConstDefault
, { ... } }

Provides shared and mutable 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

Implementors ought not mutate fields inside their accessor trait impls, or the accessor trait impls of other fields.

The safety requirements for GetFielfMut::get_field_raw_mut also apply to GetVariantFieldMut::get_vfield_raw_mut_.

IsVariant<V> and GetVariantFieldMut<V, F> must agree on what variant the enum currently is. If IsVariant returns true for a particular V variant, then get_vfield_mut_ and get_vfield_raw_mut_ 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::GetVariantFieldMut;
use structural::for_examples::{Bomb,WithBoom};
use structural::{StructuralExt,TS,fp};

fn example<T>(this: &mut T)
where
    T: GetVariantFieldMut<TS!(Boom),TS!(a),Ty= &'static str>+
       GetVariantFieldMut<TS!(Boom),TS!(b),Ty= &'static [u16]>,
{
    assert_eq!( this.field_(fp!(::Boom.a)), Some(&"why?") );
    assert_eq!( this.field_mut(fp!(::Boom.a)), Some(&mut "why?") );

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

    assert_eq!( this.cloned_fields(fp!(::Boom=>a,b)), Some(( "why?", &[0,1,2][..] )) );

    assert_eq!(
        this.fields_mut(fp!(::Boom=>a,b)),
        Some(( &mut "why?", &mut &[0,1,2][..] )),
    );

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

example(&mut WithBoom::Boom{ a:"why?", b:&[0,1,2] });
example(&mut Bomb::Boom{ a:"why?", b:&[0,1,2] });

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

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


using_enum(&mut Foo::Bar(34,51), &mut 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,
        }
    }
}

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

    unsafe fn get_vfield_raw_mut_(
        this:*mut  (),
        _:TS!(Bar),
        _:TS!(0),
    )->Option<std::ptr::NonNull<u32>> {
        structural::z_raw_borrow_enum_field!(this as *mut  Self, Foo::Bar.0 : u32)
    }

    structural::z_unsafe_impl_get_vfield_raw_mut_fn!{
        Self= Self,
        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 GetVariantFieldMut<TS!(Bar),TS!(1)> for Foo {
    fn get_vfield_mut_(&mut self, _:TS!(Bar), _:TS!(1))->Option<&mut u64>{
        match self {
            Foo::Bar(_,ret)=>Some(ret),
            _=>None
        }
    }

    unsafe fn get_vfield_raw_mut_(
        this:*mut  (),
        _:TS!(Bar),
        _:TS!(1),
    )->Option<std::ptr::NonNull<u64>> {
        structural::z_raw_borrow_enum_field!(this as *mut  Self, Foo::Bar.1 : u64)
    }

    structural::z_unsafe_impl_get_vfield_raw_mut_fn!{
        Self= Self,
        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{
        mut Bar(u32,u64),
        mut Baz,
    }
}

Required methods

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

Accesses the F field in the V variant by mutable reference.

unsafe fn get_vfield_raw_mut_(
    ptr: *mut (),
    variant: V,
    field: F
) -> Option<NonNull<Self::Ty>> where
    Self: Sized

Accesses the F field in the V variant by raw pointer.

Safety

You must pass a pointer casted from *mut Self to *mut (), pointing to a fully initialized instance of the type.

This function returns a NonNull purely as an optimization detail, functions that return raw pointers (*mut _) are also expected to return pointers to valid fields.

fn get_vfield_raw_mut_fn(&self) -> GetVFieldRawMutFn<V, F, Self::Ty>

Gets a function pointer to the get_vfield_raw_mut_ method.

This exists so that the method can be called in dyn Traits

fn get_vfield_raw_mut_unchecked_fn(&self) -> GetFieldRawMutFn<F, Self::Ty>

Gets a function pointer to the get_vfield_raw_mut_unchecked method.

This exists so that the method can be called in dyn Traits

Loading content...

Provided methods

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

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

Safety

The enum must be the V variant.

unsafe fn get_vfield_raw_mut_unchecked(ptr: *mut (), field: F) -> *mut Self::Ty where
    Self: Sized,
    V: ConstDefault

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

Safety

You must pass a pointer casted from *mut Self to *mut (), pointing to a fully initialized instance of the type.

The enum must also be the V variant (type parameter of this trait).

Loading content...

Implementations on Foreign Types

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

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

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

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

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

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

Loading content...

Implementors

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

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

Loading content...