deconstruct_moving_ptr

Macro deconstruct_moving_ptr 

Source
macro_rules! deconstruct_moving_ptr {
    ({ let tuple { $($field_index:tt: $pattern:pat),* $(,)? } = $ptr:expr ;}) => { ... };
    ({ let MaybeUninit::<tuple> { $($field_index:tt: $pattern:pat),* $(,)? } = $ptr:expr ;}) => { ... };
    ({ let $struct_name:ident { $($field_index:tt$(: $pattern:pat)?),* $(,)? } = $ptr:expr ;}) => { ... };
    ({ let MaybeUninit::<$struct_name:ident> { $($field_index:tt$(: $pattern:pat)?),* $(,)? } = $ptr:expr ;}) => { ... };
}
Expand description

Deconstructs a MovingPtr into its individual fields.

This consumes the MovingPtr and hands out MovingPtr wrappers around pointers to each of its fields. The value will not be dropped.

The macro should wrap a let expression with a struct pattern. It does not support matching tuples by position, so for tuple structs you should use 0: pat syntax.

For tuples themselves, pass the identifier tuple instead of the struct name, like let tuple { 0: pat0, 1: pat1 } = value.

This can also project into MaybeUninit. Wrap the type name or tuple with MaybeUninit::<_>, and the macro will deconstruct a MovingPtr<MaybeUninit<ParentType>> into MovingPtr<MaybeUninit<FieldType>> values.

§Examples

§Structs

use core::mem::{offset_of, MaybeUninit};
use bevy_ptr::{MovingPtr, move_as_ptr};


let parent = Parent {
  field_a: FieldAType(11),
  field_b: FieldBType(22),
  field_c: FieldCType(33),
};

let mut target_a = FieldAType(101);
let mut target_b = FieldBType(102);
let mut target_c = FieldCType(103);

// Converts `parent` into a `MovingPtr`
move_as_ptr!(parent);

// The field names must match the name used in the type definition.
// Each one will be a `MovingPtr` of the field's type.
bevy_ptr::deconstruct_moving_ptr!({
  let Parent { field_a, field_b, field_c } = parent;
});

field_a.assign_to(&mut target_a);
field_b.assign_to(&mut target_b);
field_c.assign_to(&mut target_c);

assert_eq!(target_a.0, 11);
assert_eq!(target_b.0, 22);
assert_eq!(target_c.0, 33);

§Tuples

use core::mem::{offset_of, MaybeUninit};
use bevy_ptr::{MovingPtr, move_as_ptr};


let parent = (
  FieldAType(11),
  FieldBType(22),
  FieldCType(33),
);

let mut target_a = FieldAType(101);
let mut target_b = FieldBType(102);
let mut target_c = FieldCType(103);

// Converts `parent` into a `MovingPtr`
move_as_ptr!(parent);

// The field names must match the name used in the type definition.
// Each one will be a `MovingPtr` of the field's type.
bevy_ptr::deconstruct_moving_ptr!({
  let tuple { 0: field_a, 1: field_b, 2: field_c } = parent;
});

field_a.assign_to(&mut target_a);
field_b.assign_to(&mut target_b);
field_c.assign_to(&mut target_c);

assert_eq!(target_a.0, 11);
assert_eq!(target_b.0, 22);
assert_eq!(target_c.0, 33);

§MaybeUninit

use core::mem::{offset_of, MaybeUninit};
use bevy_ptr::{MovingPtr, move_as_ptr};


let parent = MaybeUninit::new(Parent {
  field_a: FieldAType(11),
  field_b: FieldBType(22),
  field_c: FieldCType(33),
});

let mut target_a = MaybeUninit::new(FieldAType(101));
let mut target_b = MaybeUninit::new(FieldBType(102));
let mut target_c = MaybeUninit::new(FieldCType(103));

// Converts `parent` into a `MovingPtr`
move_as_ptr!(parent);

// The field names must match the name used in the type definition.
// Each one will be a `MovingPtr` of the field's type.
bevy_ptr::deconstruct_moving_ptr!({
  let MaybeUninit::<Parent> { field_a, field_b, field_c } = parent;
});

field_a.assign_to(&mut target_a);
field_b.assign_to(&mut target_b);
field_c.assign_to(&mut target_c);

unsafe {
  assert_eq!(target_a.assume_init().0, 11);
  assert_eq!(target_b.assume_init().0, 22);
  assert_eq!(target_c.assume_init().0, 33);
}