Trait repr_offset::get_field_offset::GetFieldOffset
source · pub unsafe trait GetFieldOffset<FN>: Sized {
type Type;
type Alignment;
type Privacy;
const OFFSET_WITH_VIS: FieldOffsetWithVis<Self, Self::Privacy, FN, Self::Type, Self::Alignment>;
}
Expand description
For getting the offset of a field given its name.
This trait exists to make it possible for the
OFF!
, off
, PUB_OFF!
, and pub_off
macros
to get the FieldOffset
of a field.
This trait is by default implemented by the unsafe_struct_field_offsets
macro,
and ReprOffset
derive macro.
§Safety
§Non-nested fields
Implementors must ensure that for any given impl of GetFieldOffset<TS!(<field_name>)>
for a type there is a <field_name>
field stored inline in the type,
accessible through .<field_name>
.
Implementors must ensure that the
OFFSET_WITH_VIS
associated constant contains the FieldOffset
for the <field_name>
field,
with the correct offset(in bytes), field type, and alignment type parameter.
Implementors must ensure that there is the only one impl of
GetFieldOffset
for that type through
which one can get the FieldOffset
for the <field_name>
field,
<field_name>
is used here to refer to any one field (eg: a field named foo
),
all mentions of that field in this section refer to the same field.
§SemVer
Impls of this trait where the Privacy
associated type is Private
can change or be removed in semver compatible versions,
Prefer using the GetPubFieldOffset
trait alias for bounds instead,
since that is for public fields.
§Type Parameter
The FN
type parameter is the path to the field that this gets the offset for, it can be:
-
A
tstr::TStr
: representing a single field, eg: (tstr::TS!(foo)
). -
A tuple of
tstr::TStr
s: representing a nested field, eg: (tstr::TS!(foo,bar,baz)
).
§Example
§Manual Implementation
This example demonstrates how you can implement GetFieldOffset
manually.
use repr_offset::{
alignment::{Aligned, Unaligned},
get_field_offset::{GetFieldOffset, FieldOffsetWithVis as FOWithVis},
privacy::{IsPublic, IsPrivate},
tstr::TS,
off, pub_off,
FieldOffset, ROExtAcc, ROExtOps,
};
#[repr(C, packed)]
struct Foo {
wheel_count: u8,
pub(crate) seat_size: u128,
pub is_automatic: bool,
}
let foo = Foo {
wheel_count: 3,
seat_size: 5,
is_automatic: false,
};
// We can get a reference because the field is aligned.
assert_eq!(foo.f_get(off!(wheel_count)), &3);
// The seat_size field is unaligned inside of Foo, so we can't get a reference.
assert_eq!(foo.f_get_copy(off!(seat_size)), 5);
// We can get a reference because the field is aligned.
//
// Also, because the field is public, you can use `pub_off` to get its FieldOffset.
assert_eq!(foo.f_get(pub_off!(is_automatic)), &false);
unsafe impl GetFieldOffset<TS!(wheel_count)> for Foo {
type Type = u8;
type Alignment = Aligned;
type Privacy = IsPrivate;
const OFFSET_WITH_VIS: FOWithVis<Self, IsPrivate, TS!(wheel_count), u8, Aligned> = unsafe {
FOWithVis::new(0)
};
}
unsafe impl GetFieldOffset<TS!(seat_size)> for Foo {
type Type = u128;
type Alignment = Unaligned;
type Privacy = IsPrivate;
const OFFSET_WITH_VIS: FOWithVis<Self, IsPrivate, TS!(seat_size), u128, Unaligned> =
unsafe{
<Self as GetFieldOffset<TS!(wheel_count)>>::OFFSET_WITH_VIS
.private_field_offset()
.next_field_offset()
.with_vis()
};
}
unsafe impl GetFieldOffset<TS!(is_automatic)> for Foo {
type Type = bool;
type Alignment = Aligned;
type Privacy = IsPublic;
const OFFSET_WITH_VIS: FOWithVis<Self, IsPublic, TS!(is_automatic), bool, Aligned> =
unsafe{
<Self as GetFieldOffset<TS!(seat_size)>>::OFFSET_WITH_VIS
.private_field_offset()
.next_field_offset()
.with_vis()
};
}
Required Associated Types§
Required Associated Constants§
sourceconst OFFSET_WITH_VIS: FieldOffsetWithVis<Self, Self::Privacy, FN, Self::Type, Self::Alignment>
const OFFSET_WITH_VIS: FieldOffsetWithVis<Self, Self::Privacy, FN, Self::Type, Self::Alignment>
The offset of the field.