Crate repr_offset[][src]

repr_offset allows computing and safely using field offsets from types with a defined layout.

Currently only #[repr(C)]/#[repr(C,packed)]/#[repr(C,align)] structs are supported.

Features

These are some of the features this library provides:

  • The ReprOffset derive macro, which outputs associated constants with the offsets of fields, and implements the GetFieldOffset trait for each field.

  • The FieldOffset type (how offsets are represented), with methods for operating on a field through a pointer to the struct, including getting a reference(or pointer) to the field.

  • The unsafe_struct_field_offsets macro as an alternative to the ReprOffset derive macro, most useful when the "derive" feature is disabled.

  • The GetFieldOffset trait, for getting the FieldOffset for a field, and the OFF!, off, PUB_OFF!, and pub_off macros for getting the FieldOffset for a field with a convenient syntax.

  • The extension traits from the ext module, which define methods for operating on a field, given a FieldOffset.

Examples

Derivation

This example demonstrates:

  • Deriving the field offset constants and GetFieldOffset trait with the ReprOffset derive macro.

  • Moving out unaligned fields through a raw pointer.

  • The off macro, and an extension trait from the ext module.

use repr_offset::ReprOffset;

use repr_offset::{ROExtRawOps, off};

use std::mem::ManuallyDrop;

#[repr(C, packed)]
#[derive(ReprOffset)]
struct Packed{
    x: u8,
    y: u64,
    z: String,
}

let mut this = ManuallyDrop::new(Packed{
    x: 5,
    y: 8,
    z: "oh,hi".to_string(),
});

let ptr: *mut Packed = &mut *this;

unsafe{
    assert_eq!( Packed::OFFSET_X.read(ptr), 5 );
    assert_eq!( Packed::OFFSET_Y.read(ptr), 8 );
    assert_eq!( Packed::OFFSET_Z.read(ptr), "oh,hi".to_string() );

    // Another way to do the same, using extension traits, and macros.
    assert_eq!( ptr.f_read(off!(x)), 5 );
    assert_eq!( ptr.f_read(off!(y)), 8 );
}

Initialization

This example demonstrates how you can:

  • Use the unsafe_struct_field_offsets macro to declare associated constants with the field offsets, and implement the GetFieldOffset trait.

  • The off macro, and an extension trait from the ext module.

  • Initialize an uninitialized struct with a functino that takes a raw pointer.


use std::mem::MaybeUninit;

use repr_offset::{
    unsafe_struct_field_offsets,
    off,
    Aligned, ROExtRawMutOps,
};

fn main(){
    unsafe {
        let mut foo = MaybeUninit::uninit();
        initialize_foo(foo.as_mut_ptr());
        assert_eq!(
            foo.assume_init(),
            Foo{ name: "foo".to_string(), x: 13, y: 21 }
        );
    }
}

/// Initializes a `Foo` through a raw pointer.
///
/// # Safety
///
/// Callers must pass a pointer to uninitialized memory with the
/// size and alignment of `Foo`
unsafe fn initialize_foo(this: *mut Foo){
    // How it's done with the inherent associated constants declared in
    // the `unsafe_struct_field_offsets` macro
    //
    Foo::OFFSET_NAME.write(this, "foo".into());
    Foo::OFFSET_X.write(this, 13);
    Foo::OFFSET_Y.write(this, 21);

    // How it's done with the extension traits from the ext module,
    // and the `off` macro that get the offsets of fields using the GetFieldOffset trait.
    this.f_write(off!(name), "foo".into());
    this.f_write(off!(x), 13);
    this.f_write(off!(y), 21);
}

#[repr(C)]
#[derive(Debug, PartialEq)]
pub struct Foo{
    pub name: String,
    pub x: u32,
    pub y: u32,
}

// This macro is unsafe to invoke because you have to ensure that:
// - All field types are listed,in declaration order.
// - The `alignment` parameter is `Unaligned` if the struct is `#[repr(C,packed)]`,
//   and `Aligned` if it's not.
unsafe_struct_field_offsets!{
    alignment =  Aligned,

    impl[] Foo {
        pub const OFFSET_NAME, name: String;
        pub const OFFSET_X, x: u32;
        pub const OFFSET_Y, y: u32;
    }
}


Dependencies

This library re-exports the ReprOffset derive macro from the repr_offset_derive crate when the "derive" feature is enabled, this is disabled by default.

It also reexports the tstr crate unconditionally, to use its TS macro as the type parameter of the GetFieldOffset trait.

Cargo features

These are the cargo features in repr_offset:

  • derive (disabled by default): Re-exports the ReprOffset derive macro from the repr_offset_derive crate.

  • "for_examples" (disabled by default): Enables the for_examples module, with types used in documentation examples.

Example of using the "derive" feature::

repr_offset = { version = "0.2", features = ["derive"] }

no-std support

This library is unconditionally #![no_std], and that is unlikely to change in the future.

Minimum Rust version

This crate support Rust back to 1.41.0.

Re-exports

pub use tstr;
pub use self::alignment::Aligned;
pub use self::alignment::Unaligned;
pub use self::ext::ROExtAcc;
pub use self::ext::ROExtOps;
pub use self::ext::ROExtRawAcc;
pub use self::ext::ROExtRawMutAcc;
pub use self::ext::ROExtRawMutOps;
pub use self::ext::ROExtRawOps;
pub use self::get_field_offset::FieldType;
pub use self::get_field_offset::GetPubFieldOffset;

Modules

alignment

Type-level encoding of enum Alignment { Aligned, Unaligned }

ext

Extension traits that use FieldOffset parameters to operate on fields.

for_examplesfor_examples

Types used for examples,

get_field_offset

Trait for getting the FieldOffset of a field, and related items.

offset_calc

Functions for calculating field offsets.

privacy

Type-level encoding of enum Privacy { IsPublic, IsPrivate }

utils

Miscelaneous functions.

Macros

OFF

Gets the FieldOffset for the passed in type and (possibly nested) field.

PUB_OFF

Gets the FieldOffset for the passed in type and (possibly nested) public field.

off

Gets the FieldOffset for a (possibly nested) field, and an optionally passed in value.

pub_off

Gets the FieldOffset for a (possibly nested) public field, and an optionally passed in value.

unsafe_struct_field_offsets

Declares a sequence of associated constants with the offsets of the listed fields, and implements the GetFieldOffset trait.

Structs

FieldOffset

Represents the offset of a (potentially nested) field inside a type.

Derive Macros

ReprOffsetderive

The ReprOffset derive macro defines associated constants with the offset of every field, and implements the GetFieldOffset trait,