[−][src]Crate repr_offset
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 theGetFieldOffset
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 theReprOffset
derive macro, most useful when the "derive" feature is disabled. -
The
GetFieldOffset
trait, for getting theFieldOffset
for a field, and theOFF!
,off
,PUB_OFF!
, andpub_off
macros for getting theFieldOffset
for a field with a convenient syntax. -
The extension traits from the
ext
module, which define methods for operating on a field, given aFieldOffset
.
Examples
Derivation
This example demonstrates:
-
Deriving the field offset constants and
GetFieldOffset
trait with theReprOffset
derive macro. -
Moving out unaligned fields through a raw pointer.
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 theGetFieldOffset
trait. -
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 theReprOffset
derive macro from therepr_offset_derive
crate. -
"for_examples"
(disabled by default): Enables thefor_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 |
ext | Extension traits that use |
for_examples | for_examples Types used for examples, |
get_field_offset | Trait for getting the |
offset_calc | Functions for calculating field offsets. |
privacy | Type-level encoding of |
utils | Miscelaneous functions. |
Macros
OFF | Gets the |
PUB_OFF | Gets the |
off | Gets the |
pub_off | Gets the |
unsafe_struct_field_offsets | Declares a sequence of associated constants with the offsets of the listed fields,
and implements the |
Structs
FieldOffset | Represents the offset of a (potentially nested) field inside a type. |
Derive Macros
ReprOffset | derive The |