proc_bitfield/example.rs
1pub mod support;
2
3use crate::*;
4use support::*;
5
6bitfield! {
7 /// A bitfield showcasing how to specify bit ranges.
8 #[derive(Clone, Copy, PartialEq, Eq)]
9 pub struct BitRanges(pub u32): Debug, FromStorage, IntoStorage, DerefStorage {
10 // A single field spanning the entire bitfield, using an unbounded range:
11 pub whole_bitfield: u32 @ .., // Bits 0 to 31
12
13 // Multi-bit field, specified using an inclusive range:
14 pub inclusive_range: u8 @ 0..=3, // Bits 0 to 3
15
16 // Multi-bit field, specified using an exclusive range:
17 pub exclusive_range: u8 @ 4..7, // Bits 4 to 6
18
19 // Multi-bit field specified using its start bit and length:
20 pub start_and_length: u8 @ 7; 5, // Bits 7 to 11
21
22 // Single-bit field, specified using an inclusive range:
23 pub single_bit_inclusive_range: u8 @ 12..=12, // Bit 12
24
25 // Single-bit field, specified using an exclusive range:
26 pub single_bit_exclusive_range: u8 @ 13..14, // Bit 13
27
28 // Single-bit field, specified using its start bit and a length of 1:
29 pub single_bit_start_and_length: u8 @ 14; 1, // Bit 14
30
31 // Single-bit boolean flag, specified using a single bit position.
32 // This is equivalent to the single-bit exclusive range, but uses the `Bit` traits instead
33 // of `Bits<T>`, and is specific to `bool` (which is conversely not allowed using bit
34 // ranges).
35 pub flag: bool @ 15, // Bit 15
36
37 // Multi-bit field placed immediately above the previous one
38 pub pack_above: u8 @ above; 4, // Bits 16 to 19
39
40 // Single-bit field placed immediately above the previous one
41 pub single_bit_pack_above: bool @ above, // Bit 20
42
43 pub flag2: bool @ 28, // Bit 28
44
45 // Multi-bit field placed immediately below the previous one
46 pub pack_below: u8 @ below; 4, // Bits 24 to 27
47
48 // Single-bit field placed immediately below the previous one
49 pub single_bit_pack_below: bool @ below, // Bit 23
50 }
51}
52
53bitfield! {
54 /// A bitfield showcasing how to specify access restrictions.
55 pub struct AccessRestrictions(pub u8): Debug, FromStorage, IntoStorage, DerefStorage {
56 // By specifying `read_only` (or `ro`), only `AccessRestrictions::read_only_flag` will be
57 // generated (no setters):
58 pub read_only_flag: bool [read_only] @ 0,
59 // Equivalent:
60 // pub read_only_flag: bool [ro] @ 0,
61
62 // By specifying `write_only` (or `wo`), only `AccessRestrictions::set_write_only_flag` and
63 // `AccessRestrictions::with_write_only_flag` will be generated (no getters):
64 pub write_only_flag: bool [write_only] @ 1,
65 // Equivalent:
66 // pub read_only_flag: bool [wo] @ 0,
67
68 // Both getters and setters will be generated without any explicit access restrictions:
69 // `AccessRestrictions::read_write_flag`, `AccessRestrictions::set_read_write_flag` and
70 // `AccessRestrictions::with_read_write_flag` will all be generated.
71 pub read_write_flag: bool @ 2,
72 }
73}
74
75bitfield! {
76 /// A bitfield showcasing how to use nested bitfields.
77 pub struct NestedBitfields(pub u16): Debug, FromStorage, IntoStorage, DerefStorage {
78 // By specifying `read_only` (or `ro`), only `NestedBitfields::read_only_nested` will be
79 // generated (no setters and no mutable reference access):
80 pub read_only_nested: nested AccessRestrictions [read_only] @ 0; 3,
81 // Equivalent:
82 // pub read_only_nested: nested AccessRestrictions [ro] @ 0; 3,
83
84 // By specifying `write_only` (or `wo`), only `NestedBitfields::with_write_only_nested` and
85 // `NestedBitfields::set_write_only_nested` will be generated (no getter and no mutable
86 // reference access):
87 pub write_only_nested: nested AccessRestrictions [write_only] @ 4; 3,
88 // Equivalent:
89 // pub write_only_nested: nested AccessRestrictions [wo] @ 4; 3,
90
91 // All accessors will be generated without any explicit access restrictions:
92 // - `NestedBitfields::read_write_nested`
93 // - `NestedBitfields::read_write_nested_mut`
94 // - `NestedBitfields::with_read_write_nested`
95 // - `NestedBitfields::set_read_write_nested`
96 pub read_write_nested: nested AccessRestrictions @ 8; 3,
97 }
98}
99
100bitfield! {
101 /// A bitfield showcasing various kinds of field type conversions.
102 pub struct FieldTypeConversions(pub u16): Debug, FromStorage, IntoStorage, DerefStorage {
103 // Infallible conversions
104
105 // Will:
106 // - Return a `U8WithParity` on reads, calling `<U8WithParity as From<u8>>::from`
107 // - Take a `u8` for writes
108 pub read_as_u8_with_parity: u8 [get U8WithParity] @ 0..=3,
109
110 // Will:
111 // - Return a `u8` on reads
112 // - Take a `U8WithParity` for writes, calling `<U8WithParity as Into<u8>>::into`
113 pub write_as_u8_with_parity: u8 [set U8WithParity] @ 4..=7,
114
115 // Will:
116 // - Return a `U8WithParity` on reads, calling `<U8WithParity as From<u8>>::from`
117 // - Take a `U8WithParity` for writes, calling `<U8WithParity as Into<u8>>::into`
118 pub as_u8_with_parity: u8 [U8WithParity] @ 8..=11,
119 // Equivalent to:
120 // pub u8_with_parity: u8 [get U8WithParity, set U8WithParity] @ 8..=11,
121
122
123 // Infallible conversion functions
124
125 // Will:
126 // - Return a `U8WithParity` on reads, calling `<U8WithParity as From<u8>>::from`
127 // - Take a `u8` for writes
128 pub read_as_u8_with_parity_fn: u8 [get_fn U8WithParity::from -> U8WithParity] @ 0..=3,
129
130 // Will:
131 // - Return a `u8` on reads
132 // - Take a `U8WithParity` for writes, calling `<U8WithParity as Into<u8>>::into`
133 pub write_as_u8_with_parity_fn: u8 [set_fn U8WithParity::into(U8WithParity)] @ 4..=7,
134
135
136 // Unsafe/unchecked conversions
137
138 // Will:
139 // - Return a `NonZeroU8` on reads, marking them as `unsafe` and calling
140 // `<NonZeroU8 as UnsafeFrom<u8>>::unsafe_from`
141 // - Take a `u8` for writes
142 pub unsafe_read_as_non_zero_u8: u8 [unsafe_get NonZeroU8] @ 0..=3,
143
144 // Will:
145 // - Return a `u8` on reads
146 // - Take a `U16` for writes, marking them as `unsafe` and calling
147 // `<U16 as UnsafeInto<u8>>::unsafe_into`
148 pub unsafe_write_as_u16: u8 [unsafe_set U16] @ 4..=7,
149
150 // Will:
151 // - Return a `SpuriouslyFailingU8` on reads, marking them as `unsafe` and calling
152 // `<SpuriouslyFailingU8 as UnsafeFrom<u8>>::unsafe_from`
153 // - Take a `SpuriouslyFailingU8` for writes, marking them as `unsafe` and calling
154 // `<SpuriouslyFailingU8 as UnsafeInto<u8>>::unsafe_into`
155 pub unsafe_as_spuriously_failing: u8 [unsafe_both SpuriouslyFailingU8] @ 8..=11,
156 // Equivalent to:
157 // pub unsafe_as_spuriously_failing: u8
158 // [unsafe_get SpuriouslyFailingU8, unsafe_set SpuriouslyFailingU8] @ 8..=11,
159
160 // Will:
161 // - Return a `NonZeroU8` on reads, marking them as `unsafe` and calling
162 // `<NonZeroU8 as UnsafeFrom<u8>>::unsafe_from`
163 // - Take a `NonZeroU8` for writes, calling `<NonZeroU8 as Into<u8>>::into`
164 pub unsafe_as_non_zero_u8: u8 [unsafe NonZeroU8] @ 12..=15,
165 // Equivalent to:
166 // pub unsafe_as_non_zero_u8: u8 [unsafe_get NonZeroU8, set NonZeroU8] @ 12..=15,
167
168
169 // Unsafe/unchecked conversion functions
170
171 // Will:
172 // - Return a `NonZeroU8` on reads, marking them as `unsafe` and calling
173 // `<NonZeroU8 as UnsafeFrom<u8>>::unsafe_from`
174 // - Take a `u8` for writes
175 pub unsafe_read_as_non_zero_u8_fn: u8 [
176 unsafe_get_fn NonZeroU8::unsafe_from -> NonZeroU8
177 ] @ 0..=3,
178
179 // Will:
180 // - Return a `u8` on reads
181 // - Take a `U16` for writes, marking them as `unsafe` and calling
182 // `<U16 as UnsafeInto<u8>>::unsafe_into`
183 pub unsafe_write_as_u16_fn: u8 [unsafe_set_fn U16::unsafe_into(U16)] @ 4..=7,
184
185
186 // Unsafe/unchecked conversions with safe accessors
187
188 // Will:
189 // - Return a `NonZeroU8` on reads, unsafely calling
190 // `<NonZeroU8 as UnsafeFrom<u8>>::unsafe_from`
191 // - Take a `u8` for writes
192 pub unsafe_read_as_non_zero_u8_safe_acc: u8 [unsafe_get! NonZeroU8] @ 0..=3,
193
194 // Will:
195 // - Return a `u8` on reads
196 // - Take a `U16` for writes, unsafely calling
197 // `<U16 as UnsafeInto<u8>>::unsafe_into`
198 pub unsafe_write_as_u16_safe_acc: u8 [unsafe_set! U16] @ 4..=7,
199
200 // Will:
201 // - Return a `SpuriouslyFailingU8` on reads, unsafely calling
202 // `<SpuriouslyFailingU8 as UnsafeFrom<u8>>::unsafe_from`
203 // - Take a `SpuriouslyFailingU8` for writes, unsafely calling
204 // `<SpuriouslyFailingU8 as UnsafeInto<u8>>::unsafe_into`
205 pub unsafe_as_spuriously_failing_safe_acc: u8 [unsafe_both! SpuriouslyFailingU8] @ 8..=11,
206 // Equivalent to:
207 // pub unsafe_as_spuriously_failing_safe_acc: u8
208 // [unsafe_get! SpuriouslyFailingU8, unsafe_set! SpuriouslyFailingU8] @ 8..=11,
209
210 // Will:
211 // - Return a `NonZeroU8` on reads, unsafely calling
212 // `<NonZeroU8 as UnsafeFrom<u8>>::unsafe_from`
213 // - Take a `NonZeroU8` for writes, calling `<NonZeroU8 as Into<u8>>::into`
214 pub unsafe_as_non_zero_u8_safe_acc: u8 [unsafe! NonZeroU8] @ 12..=15,
215 // Equivalent to:
216 // pub unsafe_as_non_zero_u8_safe_acc: u8 [unsafe_get! NonZeroU8, set NonZeroU8] @ 12..=15,
217
218
219 // Unsafe/unchecked conversion functions with safe accessors
220
221 // Will:
222 // - Return a `NonZeroU8` on reads, unsafely calling
223 // `<NonZeroU8 as UnsafeFrom<u8>>::unsafe_from`
224 // - Take a `u8` for writes
225 pub unsafe_read_as_non_zero_u8_fn_safe_acc: u8 [
226 unsafe_get_fn! NonZeroU8::unsafe_from -> NonZeroU8
227 ] @ 0..=3,
228
229 // Will:
230 // - Return a `u8` on reads
231 // - Take a `U16` for writes, unsafely calling `<U16 as UnsafeInto<u8>>::unsafe_into`
232 pub unsafe_write_as_u16_fn_safe_acc: u8 [unsafe_set_fn! U16::unsafe_into(U16)] @ 4..=7,
233
234
235 // Fallible conversions
236
237 // Will:
238 // - Return a `Result<NonZeroU8, TryFromIntError>` on reads, calling
239 // `<NonZeroU8 as TryFrom<u8>>::try_from`
240 // - Take a `u8` for writes
241 pub try_read_as_non_zero_u8: u8 [try_get NonZeroU8] @ 0..=3,
242
243 // Will:
244 // - Return a `u8` on reads
245 // - Take a `U16` for writes, returning `Result<(), TryFromIntError>` and calling
246 // `<U16 as TryInto<u8>>::try_into`
247 pub try_write_as_u16: u8 [try_set U16] @ 4..=7,
248
249 // Will:
250 // - Return a `Result<SpuriouslyFailingU8, ()>` on reads, calling
251 // `<SpuriouslyFailingU8 as TryFrom<u8>>::try_from`
252 // - Take a `SpuriouslyFailingU8` for writes, returning `Result<(), ()>` and calling
253 // `<SpuriouslyFailingU8 as TryInto<u8>>::try_into`
254 pub try_both_as_spuriously_failing: u8 [try_both SpuriouslyFailingU8] @ 8..=11,
255 // Equivalent to:
256 // pub try_both_as_spuriously_failing: u8
257 // [try_get SpuriouslyFailingU8, try_set SpuriouslyFailingU8] @ 8..=11,
258
259 // Will:
260 // - Return a `Result<NonZeroU8, TryFromIntError>` on reads, calling
261 // `<NonZeroU8 as TryFrom<u8>>::try_from`
262 // - Take a `NonZeroU8` for writes, calling `<NonZeroU8 as Into<u8>>::into`
263 pub try_as_non_zero_u8: u8 [try NonZeroU8] @ 12..=15,
264 // Equivalent to:
265 // pub try_as_non_zero_u8: u8 [try_get NonZeroU8, set NonZeroU8] @ 12..=15,
266
267
268 // Fallible conversion functions
269
270 // Will:
271 // - Return a `Result<NonZeroU8, TryFromIntError>` on reads, calling
272 // `<NonZeroU8 as TryFrom<u8>>::try_from`
273 // - Take a `u8` for writes
274 pub try_read_as_non_zero_u8_fn: u8 [
275 try_get_fn NonZeroU8::try_from -> Result<NonZeroU8, TryFromIntError>
276 ] @ 0..=3,
277
278 // Will:
279 // - Return a `u8` on reads
280 // - Take a `U16` for writes, returning `Result<(), TryFromIntError>` and calling
281 // `<U16 as TryInto<u8>>::try_into`
282 pub try_write_as_u16_fn: u8 [
283 try_set_fn U16::try_into(U16) -> Result<u8, TryFromIntError>
284 ] @ 4..=7,
285
286
287 // Unwrapping conversions
288
289 // Will:
290 // - Return a `NonZeroU8` on reads, calling `<NonZeroU8 as TryFrom<u8>>::try_from` and
291 // unwrapping the result
292 // - Take a `u8` for writes
293 pub unwrap_read_as_non_zero_u8: u8 [unwrap_get NonZeroU8] @ 0..=3,
294
295 // Will:
296 // - Return a `u8` on reads
297 // - Take a `U16` for writes, returning `()`, calling `<U16 as TryInto<u8>>::try_into` and
298 // unwrapping the result
299 pub unwrap_write_as_u16: u8 [unwrap_set U16] @ 4..=7,
300
301 // Will:
302 // - Return a `SpuriouslyFailingU8` on reads, calling
303 // `<SpuriouslyFailingU8 as TryFrom<u8>>::try_from` and unwrapping the result
304 // - Take a `SpuriouslyFailingU8` for writes, returning `()`, calling
305 // `<SpuriouslyFailingU8 as TryInto<u8>>::try_into` and unwrapping the result
306 pub unwrap_both_as_spuriously_failing: u8 [unwrap_both SpuriouslyFailingU8] @ 8..=11,
307 // Equivalent to:
308 // pub try_both_as_spuriously_failing: u8
309 // [try_get SpuriouslyFailingU8, try_set SpuriouslyFailingU8] @ 8..=11,
310
311 // Will:
312 // - Return a `NonZeroU8` on reads, calling `<NonZeroU8 as TryFrom<u8>>::try_from` and
313 // unwrapping the result
314 // - Take a `NonZeroU8` for writes, calling `<NonZeroU8 as Into<u8>>::into`
315 pub unwrap_as_non_zero_u8: u8 [unwrap NonZeroU8] @ 12..=15,
316 // Equivalent to:
317 // pub unwrap_as_non_zero_u8: u8 [unwrap_get NonZeroU8, set NonZeroU8] @ 12..=15,
318
319
320 // Unwrapping conversion functions
321
322 // Will:
323 // - Return a `NonZeroU8` on reads, calling `<NonZeroU8 as TryFrom<u8>>::try_from` and
324 // unwrapping the result
325 // - Take a `u8` for writes
326 pub unwrap_read_as_non_zero_u8_fn: u8 [unwrap_get_fn NonZeroU8::try_from -> NonZeroU8] @ 0..=3,
327
328 // Will:
329 // - Return a `u8` on reads
330 // - Take a `U16` for writes, returning `()`, calling `<U16 as TryInto<u8>>::try_into` and
331 // unwrapping the result
332 pub unwrap_write_as_u16_fn: u8 [unwrap_set_fn U16::try_into(U16)] @ 4..=7,
333 }
334}
335
336/// An enum showcasing the `ConvRaw` derive for converting from/into integers.
337#[derive(ConvRaw)]
338pub enum ConvRawIntExample {
339 A,
340 B = 2,
341 C,
342 D = -1,
343 E = 1,
344 F = -128,
345 G = 128,
346}
347
348/// An enum showcasing the `ConvRaw` derive for converting from/into booleans.
349#[derive(ConvRaw)]
350pub enum ConvRawBoolExample {
351 False, // Implicitly, this value is treated as 0 (false).
352 True,
353}
354
355#[cfg(feature = "nightly")]
356#[cfg_attr(all(doc, feature = "nightly"), doc(cfg(feature = "nightly")))]
357/// A type showcasing the `UnwrapBits` derive.
358#[derive(UnwrapBits)]
359pub struct UnwrapBitsExample(NonZeroU8);