Expand description
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
ReprOffsetderive macro, which outputs associated constants with the offsets of fields, and implements theGetFieldOffsettrait for each field. -
The
FieldOffsettype (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_offsetsmacro as an alternative to theReprOffsetderive macro, most useful when the “derive” feature is disabled. -
The
GetFieldOffsettrait, for getting theFieldOffsetfor a field, and theOFF!,off,PUB_OFF!, andpub_offmacros for getting theFieldOffsetfor a field with a convenient syntax. -
The extension traits from the
extmodule, which define methods for operating on a field, given aFieldOffset.
§Examples
§Derivation
This example demonstrates:
-
Deriving the field offset constants and
GetFieldOffsettrait with theReprOffsetderive macro. -
Moving out unaligned fields through a raw pointer.
use repr_offset_derive::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_offsetsmacro to declare associated constants with the field offsets, and implement theGetFieldOffsettrait. -
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::<Foo>::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,
// the `off` macro, and 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): Enables theReprOffsetderive macro. This requires the same Rust versions assyn, which is currently>= 1.56.0. -
"for_examples"(disabled by default): Enables thefor_examplesmodule, 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 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;pub use tstr;
Modules§
- alignment
- Type-level encoding of
enum Alignment { Aligned, Unaligned } - ext
- Extension traits that use
FieldOffsetparameters to operate on fields. - for_
examples - Types used for examples,
- get_
field_ offset - Trait for getting the
FieldOffsetof 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
FieldOffsetfor the passed in type and (possibly nested) field. - PUB_OFF
- Gets the
FieldOffsetfor the passed in type and (possibly nested) public field. - off
- Gets the
FieldOffsetfor a (possibly nested) field, and an optionally passed in value. - pub_off
- Gets the
FieldOffsetfor 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
GetFieldOffsettrait.
Structs§
- Field
Offset - Represents the offset of a (potentially nested) field inside a type.