1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/// A marker type representing that a `FieldOffset` is for an aligned field.
#[derive(Debug, Copy, Clone)]
pub struct Aligned;

/// A marker type representing that a `FieldOffset` is for a (potentially) unaligned field.
#[derive(Debug, Copy, Clone)]
pub struct Unaligned;

mod sealed {
    use super::{Aligned, Unaligned};
    pub trait Sealed {}

    impl Sealed for Aligned {}
    impl Sealed for Unaligned {}
}
use self::sealed::Sealed;

/// Marker trait for types that represents the alignment of a `FieldOffset`.
///
/// This is only implemented by [`Aligned`] and [`Unaligned`]
///
/// [`Aligned`]:  ./struct.Aligned.html
/// [`Unaligned`]: ./struct.Unaligned.html
pub trait Alignment: Sealed {}

impl Alignment for Aligned {}
impl Alignment for Unaligned {}

/// Combines two [`Alignment`] types,
/// determines the return type of `FieldOffset + FieldOffset`.
///
/// [`Alignment`]: ./trait.Alignment.html
/// [`FieldOffset + FieldOffset`]: ./struct.FieldOffset.html#impl-Add<FieldOffset<F%2C F2%2C A2>>
pub type CombinePackingOut<Lhs, Rhs> = <Lhs as CombinePacking<Rhs>>::Output;

/// Trait that combines two [`Alignment`] types,
/// determines the return type of `FieldOffset + FieldOffset`.
///
/// [`Alignment`]: ./trait.Alignment.html
pub trait CombinePacking<Rhs: Alignment>: Alignment {
    /// This is [`Aligned`] if both `Self` and the `Rhs` parameter are [`Aligned`],
    /// otherwise it is [`Unaligned`].
    ///
    /// [`Alignment`]: ./trait.Alignment.html
    /// [`Aligned`]:  ./struct.Aligned.html
    /// [`Unaligned`]: ./struct.Unaligned.html
    type Output: Alignment;
}

impl<A: Alignment> CombinePacking<A> for Aligned {
    type Output = A;
}
impl<A: Alignment> CombinePacking<A> for Unaligned {
    type Output = Unaligned;
}