[][src]Derive Macro const_field_offset::FieldOffsets

#[derive(FieldOffsets)]
{
    // Attributes available to this derive:
    #[const_field_offset]
    #[pin]
    #[pin_drop]
}

The macro FieldOffsets adds a FIELD_OFFSETS associated const to the struct. That is an object which has fields with the same name as the fields of the original struct, each field is of type const_field_offset::FieldOffset

use const_field_offset::FieldOffsets;
#[repr(C)]
#[derive(FieldOffsets)]
struct Foo {
    field_1 : u8,
    field_2 : u32,
}

const FOO : usize = Foo::FIELD_OFFSETS.field_2.get_byte_offset();
assert_eq!(FOO, 4);

// This would not work on stable rust at the moment (rust 1.43)
// const FOO : usize = memofsets::offsetof!(Foo, field_2);

Limitations

Only work with named #[repr(C)] structures.

Attributes

pin

Add a AllowPin to the FieldOffset.

In order for this to be safe, the macro will add code to prevent a custom Drop or Unpin implementation.

use const_field_offset::*;
#[repr(C)]
#[derive(FieldOffsets)]
#[pin]
struct Foo {
    field_1 : u8,
    field_2 : u32,
}

const FIELD_2 : FieldOffset<Foo, u32, AllowPin> = Foo::FIELD_OFFSETS.field_2;
let pin_box = Box::pin(Foo{field_1: 1, field_2: 2});
assert_eq!(*FIELD_2.apply_pin(pin_box.as_ref()), 2);

pin_drop

This attribute works like the pin attribute but it does not prevent a custom Drop implementation. Instead it provides a Drop implementation that forwards to the PinnedDrop trait that you need to implement for our type.

use const_field_offset::*;
use core::pin::Pin;

struct TypeThatRequiresSpecialDropHandling(); // ...

#[repr(C)]
#[derive(FieldOffsets)]
#[pin_drop]
struct Foo {
    field : TypeThatRequiresSpecialDropHandling,
}

impl PinnedDrop for Foo {
    fn drop(self: Pin<&mut Self>) {
        // Do you safe drop handling here
    }
}

const-field-offset

In case the const-field-offset crate is re-exported, it is possible to specify the crate name using the const_field_offset attribute.

// suppose you re-export the const_field_offset create from a different module
mod xxx { pub use const_field_offset as cfo; }
#[repr(C)]
#[derive(xxx::cfo::FieldOffsets)]
#[const_field_offset(xxx::cfo)]
struct Foo {
    field_1 : u8,
    field_2 : u32,
}