Macro memoffset::span_of

source ·
macro_rules! span_of {
    (@helper  $root:ident, [] ..=) => { ... };
    (@helper $root:ident, [] ..) => { ... };
    (@helper $root:ident, $parent:path, [] ..) => { ... };
    (@helper $root:ident, $parent:path, [] ..= $end:tt) => { ... };
    (@helper $root:ident, $parent:path, [] .. $end:tt) => { ... };
    (@helper $root:ident, $parent:path, # $begin:tt [] ..= $end:tt) => { ... };
    (@helper $root:ident, $parent:path, # $begin:tt [] .. $end:tt) => { ... };
    (@helper $root:ident, $parent:path, # $begin:tt [] ..) => { ... };
    (@helper $root:ident, $parent:path, # $begin:tt [] ..=) => { ... };
    (@helper $root:ident, $parent:path, # $field:tt []) => { ... };
    (@helper $root:ident, $parent:path, $(# $begin:tt)+ [] $tt:tt $($rest:tt)*) => { ... };
    (@helper $root:ident, $parent:path, [] $tt:tt $($rest:tt)*) => { ... };
    ($sty:path, $($exp:tt)+) => { ... };
}
Expand description

Produces a range instance representing the sub-slice containing the specified member.

This macro provides 2 forms of differing functionalities.

The first form is identical to the appearance of the offset_of! macro.

span_of!(Struct, member)

The second form of span_of! returns a sub-slice which starts at one field, and ends at another. The general pattern of this form is:

// Exclusive
span_of!(Struct, member_a .. member_b)
// Inclusive
span_of!(Struct, member_a ..= member_b)

// Open-ended ranges
span_of!(Struct, .. end)
span_of!(Struct, start ..)

Note

This macro uses recursion in order to resolve the range expressions, so there is a limit to the complexity of the expression. In order to raise the limit, the compiler’s recursion limit should be lifted.

Safety

The inter-field form mentioned above assumes that the first field is positioned before the second. This is only guarenteed for repr(C) structs. Usage with repr(Rust) structs may yield unexpected results, like downward-going ranges, spans that include unexpected fields, empty spans, or spans that include unexpected padding bytes.

Examples

use memoffset::span_of;

#[repr(C)]
struct Florp {
    a: u32
}

#[repr(C)]
struct Blarg {
    x: [u32; 2],
    y: [u8; 56],
    z: Florp,
    egg: [[u8; 4]; 4]
}

fn main() {
    assert_eq!(0..84,  span_of!(Blarg, ..));
    assert_eq!(0..8,   span_of!(Blarg, .. y));
    assert_eq!(0..64,  span_of!(Blarg, ..= y));
    assert_eq!(0..8,   span_of!(Blarg, x));
    assert_eq!(8..84,  span_of!(Blarg, y ..));
    assert_eq!(0..8,   span_of!(Blarg, x .. y));
    assert_eq!(0..64,  span_of!(Blarg, x ..= y));
}