modular_bitfield/private/
checks.rs

1pub(crate) mod private {
2    /// Prevents internal traits from being implemented from dependencies.
3    pub trait Sealed {}
4}
5
6macro_rules! impl_sealed_for {
7    ( $($primitive:ty),* ) => {
8        $(
9            impl private::Sealed for $primitive {}
10        )*
11    }
12}
13impl_sealed_for!(bool, u8, u16, u32, u64, u128);
14
15/// Helper trait to check whether the size of bitfield structs
16/// is a multiple of 8 to form complete bytes.
17pub trait TotalSizeIsMultipleOfEightBits: private::Sealed {}
18
19/// Helper trait used to check whether a bitfield struct does not
20/// fill its entire value space, e.g. has undefined bits.
21pub trait TotalSizeIsNotMultipleOfEightBits: private::Sealed {}
22
23/// Helper trait to improve compile error messages.
24pub trait RenameSizeType: private::Sealed {
25    type CheckType;
26}
27
28/// Helper type to sum up bit size of a bitfield at compile time.
29pub struct TotalSize<T>(::core::marker::PhantomData<T>);
30
31macro_rules! impl_total_size_for {
32    ( $(($n:expr, $name:ident)),* ) => {
33        $(
34            pub enum $name {}
35            impl private::Sealed for TotalSize<[(); $n]> {}
36            impl private::Sealed for $name {}
37            impl RenameSizeType for TotalSize<[(); $n]> {
38                type CheckType = $name;
39            }
40        )*
41    }
42}
43
44impl_total_size_for!(
45    (0, ZeroMod8),
46    (1, OneMod8),
47    (2, TwoMod8),
48    (3, ThreeMod8),
49    (4, FourMod8),
50    (5, FiveMod8),
51    (6, SixMod8),
52    (7, SevenMod8)
53);
54
55impl TotalSizeIsMultipleOfEightBits for ZeroMod8 {}
56
57impl TotalSizeIsNotMultipleOfEightBits for OneMod8 {}
58impl TotalSizeIsNotMultipleOfEightBits for TwoMod8 {}
59impl TotalSizeIsNotMultipleOfEightBits for ThreeMod8 {}
60impl TotalSizeIsNotMultipleOfEightBits for FourMod8 {}
61impl TotalSizeIsNotMultipleOfEightBits for FiveMod8 {}
62impl TotalSizeIsNotMultipleOfEightBits for SixMod8 {}
63impl TotalSizeIsNotMultipleOfEightBits for SevenMod8 {}
64
65/// Public facing trait implemented by bitfield structs in order to let the compiler
66/// check if their sizes match a multiple of 8.
67pub trait CheckTotalSizeMultipleOf8
68where
69    <Self::Size as RenameSizeType>::CheckType: TotalSizeIsMultipleOfEightBits,
70{
71    type Size: RenameSizeType;
72}
73
74/// Public facing trait implemented by bitfield structs in order to let the compiler
75/// check if their sizes does not match a multiple of 8.
76pub trait CheckTotalSizeIsNotMultipleOf8
77where
78    <Self::Size as RenameSizeType>::CheckType: TotalSizeIsNotMultipleOfEightBits,
79{
80    type Size: RenameSizeType;
81}
82
83/// Helper trait to check if an enum discriminant of a bitfield specifier
84/// is within valid bounds.
85pub trait DiscriminantInRange: private::Sealed {}
86
87/// Helper trait to check if a `#[derive(BitfieldSpecifier)]` flagged bitfield
88/// requires
89/// at most 128 bits.
90pub trait SpecifierHasAtMost128Bits: private::Sealed {}
91
92/// Helper type to state that something is `true`.
93///
94/// # Note
95///
96/// Used for some compile time evaluation contexts.
97pub enum True {}
98
99/// Helper type to state that something is `false`.
100///
101/// # Note
102///
103/// Used for some compile time evaluation contexts.
104pub enum False {}
105
106impl private::Sealed for True {}
107impl DiscriminantInRange for True {}
108impl SpecifierHasAtMost128Bits for True {}
109impl FillsUnalignedBits for True {}
110impl DoesNotFillUnalignedBits for True {}
111
112/// Helper trait to improve compile time error messages.
113pub trait DispatchTrueFalse: private::Sealed {
114    type Out;
115}
116
117impl private::Sealed for [(); 0] {}
118impl DispatchTrueFalse for [(); 0] {
119    type Out = False;
120}
121
122// impl private::Sealed for [(); 1] {} // <-- Already implemented by `define_specifiers` macro!
123impl DispatchTrueFalse for [(); 1] {
124    type Out = True;
125}
126
127/// Public facing trait that is implemented by bitfield specifiers to
128/// let the compiler check if all its variant discriminants are within
129/// valid bounds.
130pub trait CheckDiscriminantInRange<A>
131where
132    <Self::CheckType as DispatchTrueFalse>::Out: DiscriminantInRange,
133{
134    type CheckType: DispatchTrueFalse;
135}
136
137/// Traits to check at compile-time if a `#[derive(BitfieldSpecifier)]` type requires
138/// no more than 128 bits.
139pub trait CheckSpecifierHasAtMost128Bits
140where
141    <Self::CheckType as DispatchTrueFalse>::Out: SpecifierHasAtMost128Bits,
142{
143    type CheckType: DispatchTrueFalse;
144}
145
146/// Helper type to check whether a bitfield member aligns to
147/// the specified bits.
148pub struct BitsCheck<A> {
149    pub arr: A,
150}
151
152pub trait CheckFillsUnalignedBits
153where
154    <Self::CheckType as DispatchTrueFalse>::Out: FillsUnalignedBits,
155{
156    type CheckType: DispatchTrueFalse;
157}
158
159pub trait FillsUnalignedBits {}
160
161pub trait CheckDoesNotFillUnalignedBits
162where
163    <Self::CheckType as DispatchTrueFalse>::Out: DoesNotFillUnalignedBits,
164{
165    type CheckType: DispatchTrueFalse;
166}
167
168pub trait DoesNotFillUnalignedBits {}