Trait IntoField

Source
pub unsafe trait IntoField<FieldName>: GetField<FieldName> + DropFields {
    // Required methods
    fn into_field_(self, field_name: FieldName) -> Self::Ty;
    unsafe fn move_out_field_(
        &mut self,
        field_name: FieldName,
        moved_fields: &mut MovedOutFields,
    ) -> Self::Ty;
}
Expand description

Converts this type into its FieldName field by value.

§Safety

§Implementing move_out_field_

The way this method is expected to be implemented is like this:

  • Move out the field using std::ptr::read or equivalent.

  • Mark the field in the moved_fields parameter as being moved out using the set_moved_out method, with a FieldBit argument unique to this field in this type (fields from different types can use the same FieldBit as fields in other types).

Every implementation of IntoField::move_out_field_ must return field(s) that no other implementation of IntoVariantField or IntoField for this type return.

The DropFields::drop_fields implementation for this type must then call is_moved_out on its MovedOutFields parameter to decide whether to drop the field, passing the same FieldBit argument as in the move_out_field_ implementation. If is_moved_out returns false, then the field must be dropped.

§Usage as Bound Example

use structural::{StructuralExt,IntoField,FP,fp};
use structural::for_examples::{Struct2,Struct3};

fn example<T>(this: T)
where
    T: IntoField<FP!(foo), Ty=Option<i8>> + IntoField<FP!(bar), Ty=&'static str>
{
    assert_eq!( this.field_(fp!(foo)), &None );
    assert_eq!( this.field_(fp!(bar)), &"great" );
    assert_eq!( this.fields(fp!(foo,bar)), (&None, &"great") );
    assert_eq!( this.cloned_fields(fp!(foo,bar)), (None, "great") );

    // This can't be called with `IntoField` you need `IntoFieldMut` for that.
    // assert_eq!( this.field_mut(fp!(bar)), &mut "great" );

    assert_eq!( this.into_fields(fp!(foo, bar)), (None, "great") );
}

example(Struct2{ foo:None, bar: "great" });
example(Struct3{ foo:None, bar: "great", baz:5 });

§Manual Implementation Example

While this trait is intended to be implemented using the Structural derive macro, you can manually implement it like this:

use structural::{FieldType,GetField,IntoField,Structural,FP};
use structural::field::ownership::{DropFields, MovedOutFields, RunDrop, FieldBit};

struct Huh<T>{
    first:T,
    second:T,
}


impl<T> Structural for Huh<T>{}


impl<T> FieldType<FP!(first)> for Huh<T>{
    type Ty=T;
}

impl<T> GetField<FP!(first)> for Huh<T>{
    fn get_field_(&self, _: FP!(first))->&Self::Ty{
        &self.first
    }
}

const FIRST_INDEX: FieldBit = FieldBit::new(0);

unsafe impl<T> IntoField<FP!(first)> for Huh<T>{
    fn into_field_(self, _: FP!(first))->Self::Ty{
        self.first
    }

    unsafe fn move_out_field_(
        &mut self,
        field_name: FP!(first),
        moved_fields: &mut MovedOutFields,
    ) -> Self::Ty {
        moved_fields.set_moved_out(FIRST_INDEX);
        std::ptr::read(&mut self.first)
    }
}


impl<T> FieldType<FP!(second)> for Huh<T>{
    type Ty=T;
}

impl<T> GetField<FP!(second)> for Huh<T>{
    fn get_field_(&self, _: FP!(second))->&Self::Ty{
        &self.second
    }
}

const SECOND_INDEX: FieldBit = FieldBit::new(1);

unsafe impl<T> IntoField<FP!(second)> for Huh<T>{
    fn into_field_(self, _: FP!(second))->Self::Ty{
        self.second
    }

    unsafe fn move_out_field_(
        &mut self,
        field_name: FP!(second),
        moved_fields: &mut MovedOutFields,
    ) -> Self::Ty {
        moved_fields.set_moved_out(SECOND_INDEX);
        std::ptr::read(&mut self.second)
    }
}


unsafe impl<T> DropFields for Huh<T>{
    // This type does nothing before fields are moved.
    fn pre_move(&mut self){}

    unsafe fn drop_fields(&mut self, moved: MovedOutFields){
        let Self{first, second} = self;

        // RunDrop here ensures that the destructors for all fields are ran
        // even if any of them panics.
        let _drop;
        if moved.is_moved_out(FIRST_INDEX) {
            _drop = unsafe{ RunDrop::new(first) };
        }
        let _drop;
        if moved.is_moved_out(SECOND_INDEX) {
            _drop = unsafe{ RunDrop::new(second) };
        }
    }
}

Required Methods§

Source

fn into_field_(self, field_name: FieldName) -> Self::Ty

Converts this into the field by value.

Source

unsafe fn move_out_field_( &mut self, field_name: FieldName, moved_fields: &mut MovedOutFields, ) -> Self::Ty

Moves out the field from self.

§Safety

The same instance of MovedOutFields must be passed to every call to move_out_field_ on the same instance of this type, as well as not mutating that MovedOutFields instance outside of methods of this trait for this type.

Each field must be moved at most once on the same instance of this type.

Implementations on Foreign Types§

Source§

impl<T, P> IntoField<P> for [T; 0]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 1]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 2]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 3]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 4]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 5]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 6]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 7]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 8]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 9]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 10]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 11]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 12]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 13]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 14]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 15]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 16]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 17]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 18]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 19]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 20]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 21]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 22]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 23]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 24]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 25]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 26]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 27]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 28]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 29]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 30]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 31]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for [T; 32]
where P: IsPathForArray<Self>,

Source§

fn into_field_(self, _: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, _field_name: P, moved: &mut MovedOutFields, ) -> T

Source§

impl<T, P> IntoField<P> for Box<T>
where T: ?Sized + IntoField<P>,

Source§

fn into_field_(self, path: P) -> Self::Ty

Source§

unsafe fn move_out_field_( &mut self, path: P, moved: &mut MovedOutFields, ) -> Self::Ty

Implementors§

Source§

impl<T, P> IntoField<P> for FieldCloner<T>
where T: GetField<P>, T::Ty: Clone,

Source§

impl<T, V, F> IntoField<F> for VariantProxy<T, V>
where T: IntoVariantField<V, F>, V: IsTStr,

Source§

impl<T, __F, __Ty> IntoField<__F> for StrucWrapper<T>
where T: IntoField<__F, Ty = __Ty>,