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::TStrs: 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§

source

type Type

The type of the field.

source

type Alignment

Whether the field is:

  • Aligned: Self has an alignment greater than or equal to the field type, usually when Self has one of the #[repr(C)]/#[repr(C, align(...))]/#[repr(transparent)] representations.

  • Unaligned: Self has an alignment smaller than the field type, usually when Self has the #[repr(C, packed)] representation.

source

type Privacy

Whether the field is private or not, either:

  • IsPublic: When the field is pub.

  • IsPrivate: When the field has the default (private) visibility, or has a visibility smaller or equal to pub(crate).

Required Associated Constants§

source

const OFFSET_WITH_VIS: FieldOffsetWithVis<Self, Self::Privacy, FN, Self::Type, Self::Alignment>

The offset of the field.

Implementors§

source§

impl<A, B, C, D> GetFieldOffset<TStr<(__a,)>> for ReprAlign4<A, B, C, D>

source§

impl<A, B, C, D> GetFieldOffset<TStr<(__a,)>> for ReprC<A, B, C, D>

source§

impl<A, B, C, D> GetFieldOffset<TStr<(__a,)>> for ReprPacked2<A, B, C, D>

source§

impl<A, B, C, D> GetFieldOffset<TStr<(__a,)>> for ReprPacked<A, B, C, D>

source§

impl<A, B, C, D> GetFieldOffset<TStr<(__b,)>> for ReprAlign4<A, B, C, D>

source§

impl<A, B, C, D> GetFieldOffset<TStr<(__b,)>> for ReprC<A, B, C, D>

source§

impl<A, B, C, D> GetFieldOffset<TStr<(__b,)>> for ReprPacked2<A, B, C, D>

source§

impl<A, B, C, D> GetFieldOffset<TStr<(__b,)>> for ReprPacked<A, B, C, D>

source§

impl<A, B, C, D> GetFieldOffset<TStr<(__c,)>> for ReprAlign4<A, B, C, D>

source§

impl<A, B, C, D> GetFieldOffset<TStr<(__c,)>> for ReprC<A, B, C, D>

source§

impl<A, B, C, D> GetFieldOffset<TStr<(__c,)>> for ReprPacked2<A, B, C, D>

source§

impl<A, B, C, D> GetFieldOffset<TStr<(__c,)>> for ReprPacked<A, B, C, D>

source§

impl<A, B, C, D> GetFieldOffset<TStr<(__d,)>> for ReprAlign4<A, B, C, D>

source§

impl<A, B, C, D> GetFieldOffset<TStr<(__d,)>> for ReprC<A, B, C, D>

source§

impl<A, B, C, D> GetFieldOffset<TStr<(__d,)>> for ReprPacked2<A, B, C, D>

source§

impl<A, B, C, D> GetFieldOffset<TStr<(__d,)>> for ReprPacked<A, B, C, D>

source§

impl<L0, L1, F0, F1, L2, CombAlign, CombPriv> GetFieldOffset<(F0, F1)> for ImplGetNestedFieldOffset<L0>where L0: ImplsGetFieldOffset + GetFieldOffset<F0, Type = L1>, L1: GetFieldOffset<F1, Type = L2>, (L0::Alignment, L1::Alignment): CombineAlignment<Aligned, Output = CombAlign>, (L0::Privacy, L1::Privacy): CombinePrivacy<IsPublic, Output = CombPriv>, CombAlign: Alignment, CombPriv: Privacy,

§

type Type = L2

§

type Alignment = CombAlign

§

type Privacy = CombPriv

source§

const OFFSET_WITH_VIS: FieldOffsetWithVis<Self, Self::Privacy, (F0, F1), L2, Self::Alignment> = _

source§

impl<L0, L1, L2, F0, F1, F2, L3, CombAlign, CombPriv> GetFieldOffset<(F0, F1, F2)> for ImplGetNestedFieldOffset<L0>where L0: ImplsGetFieldOffset + GetFieldOffset<F0, Type = L1>, L1: GetFieldOffset<F1, Type = L2>, L2: GetFieldOffset<F2, Type = L3>, (L0::Alignment, L1::Alignment, L2::Alignment): CombineAlignment<Aligned, Output = CombAlign>, (L0::Privacy, L1::Privacy, L2::Privacy): CombinePrivacy<IsPublic, Output = CombPriv>, CombAlign: Alignment, CombPriv: Privacy,

§

type Type = L3

§

type Alignment = CombAlign

§

type Privacy = CombPriv

source§

const OFFSET_WITH_VIS: FieldOffsetWithVis<Self, Self::Privacy, (F0, F1, F2), L3, Self::Alignment> = _

source§

impl<L0, L1, L2, L3, F0, F1, F2, F3, L4, CombAlign, CombPriv> GetFieldOffset<(F0, F1, F2, F3)> for ImplGetNestedFieldOffset<L0>where L0: ImplsGetFieldOffset + GetFieldOffset<F0, Type = L1>, L1: GetFieldOffset<F1, Type = L2>, L2: GetFieldOffset<F2, Type = L3>, L3: GetFieldOffset<F3, Type = L4>, (L0::Alignment, L1::Alignment, L2::Alignment, L3::Alignment): CombineAlignment<Aligned, Output = CombAlign>, (L0::Privacy, L1::Privacy, L2::Privacy, L3::Privacy): CombinePrivacy<IsPublic, Output = CombPriv>, CombAlign: Alignment, CombPriv: Privacy,

§

type Type = L4

§

type Alignment = CombAlign

§

type Privacy = CombPriv

source§

const OFFSET_WITH_VIS: FieldOffsetWithVis<Self, Self::Privacy, (F0, F1, F2, F3), L4, Self::Alignment> = _

source§

impl<L0, L1, L2, L3, L4, F0, F1, F2, F3, F4, L5, CombAlign, CombPriv> GetFieldOffset<(F0, F1, F2, F3, F4)> for ImplGetNestedFieldOffset<L0>where L0: ImplsGetFieldOffset + GetFieldOffset<F0, Type = L1>, L1: GetFieldOffset<F1, Type = L2>, L2: GetFieldOffset<F2, Type = L3>, L3: GetFieldOffset<F3, Type = L4>, L4: GetFieldOffset<F4, Type = L5>, (L0::Alignment, L1::Alignment, L2::Alignment, L3::Alignment, L4::Alignment): CombineAlignment<Aligned, Output = CombAlign>, (L0::Privacy, L1::Privacy, L2::Privacy, L3::Privacy, L4::Privacy): CombinePrivacy<IsPublic, Output = CombPriv>, CombAlign: Alignment, CombPriv: Privacy,

§

type Type = L5

§

type Alignment = CombAlign

§

type Privacy = CombPriv

source§

const OFFSET_WITH_VIS: FieldOffsetWithVis<Self, Self::Privacy, (F0, F1, F2, F3, F4), L5, Self::Alignment> = _

source§

impl<L0, L1, L2, L3, L4, L5, F0, F1, F2, F3, F4, F5, L6, CombAlign, CombPriv> GetFieldOffset<(F0, F1, F2, F3, F4, F5)> for ImplGetNestedFieldOffset<L0>where L0: ImplsGetFieldOffset + GetFieldOffset<F0, Type = L1>, L1: GetFieldOffset<F1, Type = L2>, L2: GetFieldOffset<F2, Type = L3>, L3: GetFieldOffset<F3, Type = L4>, L4: GetFieldOffset<F4, Type = L5>, L5: GetFieldOffset<F5, Type = L6>, (L0::Alignment, L1::Alignment, L2::Alignment, L3::Alignment, L4::Alignment, L5::Alignment): CombineAlignment<Aligned, Output = CombAlign>, (L0::Privacy, L1::Privacy, L2::Privacy, L3::Privacy, L4::Privacy, L5::Privacy): CombinePrivacy<IsPublic, Output = CombPriv>, CombAlign: Alignment, CombPriv: Privacy,

§

type Type = L6

§

type Alignment = CombAlign

§

type Privacy = CombPriv

source§

const OFFSET_WITH_VIS: FieldOffsetWithVis<Self, Self::Privacy, (F0, F1, F2, F3, F4, F5), L6, Self::Alignment> = _

source§

impl<L0, L1, L2, L3, L4, L5, L6, F0, F1, F2, F3, F4, F5, F6, L7, CombAlign, CombPriv> GetFieldOffset<(F0, F1, F2, F3, F4, F5, F6)> for ImplGetNestedFieldOffset<L0>where L0: ImplsGetFieldOffset + GetFieldOffset<F0, Type = L1>, L1: GetFieldOffset<F1, Type = L2>, L2: GetFieldOffset<F2, Type = L3>, L3: GetFieldOffset<F3, Type = L4>, L4: GetFieldOffset<F4, Type = L5>, L5: GetFieldOffset<F5, Type = L6>, L6: GetFieldOffset<F6, Type = L7>, (L0::Alignment, L1::Alignment, L2::Alignment, L3::Alignment, L4::Alignment, L5::Alignment, L6::Alignment): CombineAlignment<Aligned, Output = CombAlign>, (L0::Privacy, L1::Privacy, L2::Privacy, L3::Privacy, L4::Privacy, L5::Privacy, L6::Privacy): CombinePrivacy<IsPublic, Output = CombPriv>, CombAlign: Alignment, CombPriv: Privacy,

§

type Type = L7

§

type Alignment = CombAlign

§

type Privacy = CombPriv

source§

const OFFSET_WITH_VIS: FieldOffsetWithVis<Self, Self::Privacy, (F0, F1, F2, F3, F4, F5, F6), L7, Self::Alignment> = _

source§

impl<L0, L1, L2, L3, L4, L5, L6, L7, F0, F1, F2, F3, F4, F5, F6, F7, L8, CombAlign, CombPriv> GetFieldOffset<(F0, F1, F2, F3, F4, F5, F6, F7)> for ImplGetNestedFieldOffset<L0>where L0: ImplsGetFieldOffset + GetFieldOffset<F0, Type = L1>, L1: GetFieldOffset<F1, Type = L2>, L2: GetFieldOffset<F2, Type = L3>, L3: GetFieldOffset<F3, Type = L4>, L4: GetFieldOffset<F4, Type = L5>, L5: GetFieldOffset<F5, Type = L6>, L6: GetFieldOffset<F6, Type = L7>, L7: GetFieldOffset<F7, Type = L8>, (L0::Alignment, L1::Alignment, L2::Alignment, L3::Alignment, L4::Alignment, L5::Alignment, L6::Alignment, L7::Alignment): CombineAlignment<Aligned, Output = CombAlign>, (L0::Privacy, L1::Privacy, L2::Privacy, L3::Privacy, L4::Privacy, L5::Privacy, L6::Privacy, L7::Privacy): CombinePrivacy<IsPublic, Output = CombPriv>, CombAlign: Alignment, CombPriv: Privacy,

§

type Type = L8

§

type Alignment = CombAlign

§

type Privacy = CombPriv

source§

const OFFSET_WITH_VIS: FieldOffsetWithVis<Self, Self::Privacy, (F0, F1, F2, F3, F4, F5, F6, F7), L8, Self::Alignment> = _

source§

impl<T, F0, F1> GetFieldOffset<(F0, F1)> for Twhere T: ImplsGetFieldOffset, ImplGetNestedFieldOffset<T>: GetFieldOffset<(F0, F1)>,

source§

impl<T, F0, F1, F2> GetFieldOffset<(F0, F1, F2)> for Twhere T: ImplsGetFieldOffset, ImplGetNestedFieldOffset<T>: GetFieldOffset<(F0, F1, F2)>,

source§

impl<T, F0, F1, F2, F3> GetFieldOffset<(F0, F1, F2, F3)> for Twhere T: ImplsGetFieldOffset, ImplGetNestedFieldOffset<T>: GetFieldOffset<(F0, F1, F2, F3)>,

source§

impl<T, F0, F1, F2, F3, F4> GetFieldOffset<(F0, F1, F2, F3, F4)> for Twhere T: ImplsGetFieldOffset, ImplGetNestedFieldOffset<T>: GetFieldOffset<(F0, F1, F2, F3, F4)>,

source§

impl<T, F0, F1, F2, F3, F4, F5> GetFieldOffset<(F0, F1, F2, F3, F4, F5)> for Twhere T: ImplsGetFieldOffset, ImplGetNestedFieldOffset<T>: GetFieldOffset<(F0, F1, F2, F3, F4, F5)>,

source§

impl<T, F0, F1, F2, F3, F4, F5, F6> GetFieldOffset<(F0, F1, F2, F3, F4, F5, F6)> for Twhere T: ImplsGetFieldOffset, ImplGetNestedFieldOffset<T>: GetFieldOffset<(F0, F1, F2, F3, F4, F5, F6)>,

source§

impl<T, F0, F1, F2, F3, F4, F5, F6, F7> GetFieldOffset<(F0, F1, F2, F3, F4, F5, F6, F7)> for Twhere T: ImplsGetFieldOffset, ImplGetNestedFieldOffset<T>: GetFieldOffset<(F0, F1, F2, F3, F4, F5, F6, F7)>,