1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2018 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker
5*bb4ee6a4SAndroid Build Coastguard Worker //! This crate provides a `#[bitfield]` attribute macro for defining structs in
6*bb4ee6a4SAndroid Build Coastguard Worker //! a packed binary representation that supports access to ranges of bits.
7*bb4ee6a4SAndroid Build Coastguard Worker //!
8*bb4ee6a4SAndroid Build Coastguard Worker //! We conceptualize one of these structs as a sequence of bits 0..N. The bits
9*bb4ee6a4SAndroid Build Coastguard Worker //! are grouped into fields in the order specified by a struct written by the
10*bb4ee6a4SAndroid Build Coastguard Worker //! caller. The `#[bitfield]` attribute rewrites the caller's struct into a
11*bb4ee6a4SAndroid Build Coastguard Worker //! private byte array representation with public getter and setter methods for
12*bb4ee6a4SAndroid Build Coastguard Worker //! each field.
13*bb4ee6a4SAndroid Build Coastguard Worker //!
14*bb4ee6a4SAndroid Build Coastguard Worker //! Byte order: note that we consider the bit `i` to be the `i % 8`'th least
15*bb4ee6a4SAndroid Build Coastguard Worker //! significant bit in the `i / 8`'th byte of the struct.
16*bb4ee6a4SAndroid Build Coastguard Worker //!
17*bb4ee6a4SAndroid Build Coastguard Worker //! The total number of bits N is required to be a multiple of 8 (this is
18*bb4ee6a4SAndroid Build Coastguard Worker //! checked at compile time).
19*bb4ee6a4SAndroid Build Coastguard Worker //!
20*bb4ee6a4SAndroid Build Coastguard Worker //! # Examples
21*bb4ee6a4SAndroid Build Coastguard Worker //!
22*bb4ee6a4SAndroid Build Coastguard Worker //! The following invocation builds a struct with a total size of 32 bits or 4
23*bb4ee6a4SAndroid Build Coastguard Worker //! bytes. It places field `a` in the least significant bit of the first byte,
24*bb4ee6a4SAndroid Build Coastguard Worker //! field `b` in the next three least significant bits, field `c` in the
25*bb4ee6a4SAndroid Build Coastguard Worker //! remaining four most significant bits of the first byte, and field `d`
26*bb4ee6a4SAndroid Build Coastguard Worker //! spanning the next three bytes. The least significant byte of `d` will be
27*bb4ee6a4SAndroid Build Coastguard Worker //! held in the second byte of our struct, adjacent to the byte holding the
28*bb4ee6a4SAndroid Build Coastguard Worker //! first three fields.
29*bb4ee6a4SAndroid Build Coastguard Worker //!
30*bb4ee6a4SAndroid Build Coastguard Worker //! ```
31*bb4ee6a4SAndroid Build Coastguard Worker //! use bit_field::*;
32*bb4ee6a4SAndroid Build Coastguard Worker //!
33*bb4ee6a4SAndroid Build Coastguard Worker //! #[bitfield]
34*bb4ee6a4SAndroid Build Coastguard Worker //! pub struct MyFourBytes {
35*bb4ee6a4SAndroid Build Coastguard Worker //! a: B1,
36*bb4ee6a4SAndroid Build Coastguard Worker //! b: B3,
37*bb4ee6a4SAndroid Build Coastguard Worker //! c: B4,
38*bb4ee6a4SAndroid Build Coastguard Worker //! d: B24,
39*bb4ee6a4SAndroid Build Coastguard Worker //! }
40*bb4ee6a4SAndroid Build Coastguard Worker //! ```
41*bb4ee6a4SAndroid Build Coastguard Worker //!
42*bb4ee6a4SAndroid Build Coastguard Worker //! ```text
43*bb4ee6a4SAndroid Build Coastguard Worker //! less significant
44*bb4ee6a4SAndroid Build Coastguard Worker //! / more significant
45*bb4ee6a4SAndroid Build Coastguard Worker //! / /
46*bb4ee6a4SAndroid Build Coastguard Worker //! (first byte) (second byte) / (third) / (fourth byte)
47*bb4ee6a4SAndroid Build Coastguard Worker //! 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
48*bb4ee6a4SAndroid Build Coastguard Worker //! | \ / \_ _/ \_______________________ _______________________/
49*bb4ee6a4SAndroid Build Coastguard Worker //! a b c less significant d more significant
50*bb4ee6a4SAndroid Build Coastguard Worker //! ```
51*bb4ee6a4SAndroid Build Coastguard Worker //!
52*bb4ee6a4SAndroid Build Coastguard Worker //! The code emitted by the `#[bitfield]` macro for this struct is as follows.
53*bb4ee6a4SAndroid Build Coastguard Worker //! Note that the field getters and setters use whichever of `u8`, `u16`, `u32`,
54*bb4ee6a4SAndroid Build Coastguard Worker //! `u64` is the smallest while being at least as large as the number of bits in
55*bb4ee6a4SAndroid Build Coastguard Worker //! the field.
56*bb4ee6a4SAndroid Build Coastguard Worker //!
57*bb4ee6a4SAndroid Build Coastguard Worker //! ```ignore
58*bb4ee6a4SAndroid Build Coastguard Worker //! impl MyFourBytes {
59*bb4ee6a4SAndroid Build Coastguard Worker //! // Initializes all fields to 0.
60*bb4ee6a4SAndroid Build Coastguard Worker //! pub fn new() -> Self;
61*bb4ee6a4SAndroid Build Coastguard Worker //!
62*bb4ee6a4SAndroid Build Coastguard Worker //! // Field getters and setters:
63*bb4ee6a4SAndroid Build Coastguard Worker //! pub fn get_a(&self) -> u8;
64*bb4ee6a4SAndroid Build Coastguard Worker //! pub fn set_a(&mut self, val: u8);
65*bb4ee6a4SAndroid Build Coastguard Worker //! pub fn get_b(&self) -> u8;
66*bb4ee6a4SAndroid Build Coastguard Worker //! pub fn set_b(&mut self, val: u8);
67*bb4ee6a4SAndroid Build Coastguard Worker //! pub fn get_c(&self) -> u8;
68*bb4ee6a4SAndroid Build Coastguard Worker //! pub fn set_c(&mut self, val: u8);
69*bb4ee6a4SAndroid Build Coastguard Worker //! pub fn get_d(&self) -> u32;
70*bb4ee6a4SAndroid Build Coastguard Worker //! pub fn set_d(&mut self, val: u32);
71*bb4ee6a4SAndroid Build Coastguard Worker //!
72*bb4ee6a4SAndroid Build Coastguard Worker //! // Bit-level accessors:
73*bb4ee6a4SAndroid Build Coastguard Worker //! pub fn get_bit(&self, offset: usize) -> bool;
74*bb4ee6a4SAndroid Build Coastguard Worker //! pub fn set_bit(&mut self, offset: usize, val: bool);
75*bb4ee6a4SAndroid Build Coastguard Worker //! pub fn get(&self, offset: usize, width: u8) -> u64;
76*bb4ee6a4SAndroid Build Coastguard Worker //! pub fn set(&mut self, offset: usize, width: u8, val: u64);
77*bb4ee6a4SAndroid Build Coastguard Worker //! }
78*bb4ee6a4SAndroid Build Coastguard Worker //! ```
79*bb4ee6a4SAndroid Build Coastguard Worker //!
80*bb4ee6a4SAndroid Build Coastguard Worker //! # Bit field specifier types
81*bb4ee6a4SAndroid Build Coastguard Worker //!
82*bb4ee6a4SAndroid Build Coastguard Worker //! Field types may be specified as B1 through B64, or alternatively as
83*bb4ee6a4SAndroid Build Coastguard Worker //! BitField1 through BitField64 in code that benefits from the clarification.
84*bb4ee6a4SAndroid Build Coastguard Worker //!
85*bb4ee6a4SAndroid Build Coastguard Worker //! Fields may also be specified as `bool`, which is laid out equivalently to
86*bb4ee6a4SAndroid Build Coastguard Worker //! `B1` but with accessors that use `bool` rather than `u8`.
87*bb4ee6a4SAndroid Build Coastguard Worker //!
88*bb4ee6a4SAndroid Build Coastguard Worker //! ```
89*bb4ee6a4SAndroid Build Coastguard Worker //! use bit_field::*;
90*bb4ee6a4SAndroid Build Coastguard Worker //!
91*bb4ee6a4SAndroid Build Coastguard Worker //! #[bitfield]
92*bb4ee6a4SAndroid Build Coastguard Worker //! pub struct MyFourBytes {
93*bb4ee6a4SAndroid Build Coastguard Worker //! a: bool,
94*bb4ee6a4SAndroid Build Coastguard Worker //! b: B3,
95*bb4ee6a4SAndroid Build Coastguard Worker //! c: B4,
96*bb4ee6a4SAndroid Build Coastguard Worker //! d: B24,
97*bb4ee6a4SAndroid Build Coastguard Worker //! }
98*bb4ee6a4SAndroid Build Coastguard Worker //! ```
99*bb4ee6a4SAndroid Build Coastguard Worker //!
100*bb4ee6a4SAndroid Build Coastguard Worker //! Fields may be user-defined single element tuple struct with primitive types. Use must specify
101*bb4ee6a4SAndroid Build Coastguard Worker //! the width with `#[bits = N]`. This should be used to improve type safety.
102*bb4ee6a4SAndroid Build Coastguard Worker //!
103*bb4ee6a4SAndroid Build Coastguard Worker //! ```
104*bb4ee6a4SAndroid Build Coastguard Worker //! use bit_field::*;
105*bb4ee6a4SAndroid Build Coastguard Worker //!
106*bb4ee6a4SAndroid Build Coastguard Worker //! #[bitfield]
107*bb4ee6a4SAndroid Build Coastguard Worker //! #[bits = 60]
108*bb4ee6a4SAndroid Build Coastguard Worker //! struct AddressField(u64);
109*bb4ee6a4SAndroid Build Coastguard Worker //!
110*bb4ee6a4SAndroid Build Coastguard Worker //! impl AddressField {
111*bb4ee6a4SAndroid Build Coastguard Worker //! pub fn new(addr: u64) -> AddressField {
112*bb4ee6a4SAndroid Build Coastguard Worker //! AddressField(addr >> 4)
113*bb4ee6a4SAndroid Build Coastguard Worker //! }
114*bb4ee6a4SAndroid Build Coastguard Worker //!
115*bb4ee6a4SAndroid Build Coastguard Worker //! pub fn get_addr(&self) -> u64 {
116*bb4ee6a4SAndroid Build Coastguard Worker //! self.0 << 4
117*bb4ee6a4SAndroid Build Coastguard Worker //! }
118*bb4ee6a4SAndroid Build Coastguard Worker //! }
119*bb4ee6a4SAndroid Build Coastguard Worker //! ```
120*bb4ee6a4SAndroid Build Coastguard Worker //!
121*bb4ee6a4SAndroid Build Coastguard Worker //! Finally, fields may be of user-defined enum types. The enum must satisfy one of the following
122*bb4ee6a4SAndroid Build Coastguard Worker //! requirements.
123*bb4ee6a4SAndroid Build Coastguard Worker //!
124*bb4ee6a4SAndroid Build Coastguard Worker //! The enum has `#[bits = N]` attributes with it. `N` will be the width of the field. The getter
125*bb4ee6a4SAndroid Build Coastguard Worker //! function of this enum field will return `Result<EnumType, u64>`. Raw value that does not match
126*bb4ee6a4SAndroid Build Coastguard Worker //! any variant will result in an `Err(u64)`.
127*bb4ee6a4SAndroid Build Coastguard Worker //!
128*bb4ee6a4SAndroid Build Coastguard Worker //! ```
129*bb4ee6a4SAndroid Build Coastguard Worker //! use bit_field::*;
130*bb4ee6a4SAndroid Build Coastguard Worker //!
131*bb4ee6a4SAndroid Build Coastguard Worker //! #[bitfield]
132*bb4ee6a4SAndroid Build Coastguard Worker //! #[bits = 2]
133*bb4ee6a4SAndroid Build Coastguard Worker //! #[derive(Debug, PartialEq)]
134*bb4ee6a4SAndroid Build Coastguard Worker //! enum TwoBits {
135*bb4ee6a4SAndroid Build Coastguard Worker //! Zero = 0b00,
136*bb4ee6a4SAndroid Build Coastguard Worker //! One = 0b01,
137*bb4ee6a4SAndroid Build Coastguard Worker //! Three = 0b11,
138*bb4ee6a4SAndroid Build Coastguard Worker //! }
139*bb4ee6a4SAndroid Build Coastguard Worker //!
140*bb4ee6a4SAndroid Build Coastguard Worker //! #[bitfield]
141*bb4ee6a4SAndroid Build Coastguard Worker //! struct Struct {
142*bb4ee6a4SAndroid Build Coastguard Worker //! prefix: BitField1,
143*bb4ee6a4SAndroid Build Coastguard Worker //! two_bits: TwoBits,
144*bb4ee6a4SAndroid Build Coastguard Worker //! suffix: BitField5,
145*bb4ee6a4SAndroid Build Coastguard Worker //! }
146*bb4ee6a4SAndroid Build Coastguard Worker //! ```
147*bb4ee6a4SAndroid Build Coastguard Worker //!
148*bb4ee6a4SAndroid Build Coastguard Worker //! The enum has a number of variants which is a power of 2 and the discriminant values
149*bb4ee6a4SAndroid Build Coastguard Worker //! (explicit or implicit) are 0 through (2^n)-1. In this case the generated
150*bb4ee6a4SAndroid Build Coastguard Worker //! getter and setter are defined in terms of the given enum type.
151*bb4ee6a4SAndroid Build Coastguard Worker //!
152*bb4ee6a4SAndroid Build Coastguard Worker //! ```
153*bb4ee6a4SAndroid Build Coastguard Worker //! use bit_field::*;
154*bb4ee6a4SAndroid Build Coastguard Worker //!
155*bb4ee6a4SAndroid Build Coastguard Worker //! #[bitfield]
156*bb4ee6a4SAndroid Build Coastguard Worker //! #[derive(Debug, PartialEq)]
157*bb4ee6a4SAndroid Build Coastguard Worker //! enum TwoBits {
158*bb4ee6a4SAndroid Build Coastguard Worker //! Zero = 0b00,
159*bb4ee6a4SAndroid Build Coastguard Worker //! One = 0b01,
160*bb4ee6a4SAndroid Build Coastguard Worker //! Two = 0b10,
161*bb4ee6a4SAndroid Build Coastguard Worker //! Three = 0b11,
162*bb4ee6a4SAndroid Build Coastguard Worker //! }
163*bb4ee6a4SAndroid Build Coastguard Worker //!
164*bb4ee6a4SAndroid Build Coastguard Worker //! #[bitfield]
165*bb4ee6a4SAndroid Build Coastguard Worker //! struct Struct {
166*bb4ee6a4SAndroid Build Coastguard Worker //! prefix: BitField1,
167*bb4ee6a4SAndroid Build Coastguard Worker //! two_bits: TwoBits,
168*bb4ee6a4SAndroid Build Coastguard Worker //! suffix: BitField5,
169*bb4ee6a4SAndroid Build Coastguard Worker //! }
170*bb4ee6a4SAndroid Build Coastguard Worker //! ```
171*bb4ee6a4SAndroid Build Coastguard Worker //!
172*bb4ee6a4SAndroid Build Coastguard Worker //! An optional `#[bits = N]` attribute may be used to document the number of
173*bb4ee6a4SAndroid Build Coastguard Worker //! bits in any field. This is intended for fields of enum type whose name does
174*bb4ee6a4SAndroid Build Coastguard Worker //! not clearly indicate the number of bits. The attribute is optional but helps
175*bb4ee6a4SAndroid Build Coastguard Worker //! make it possible to read off the field sizes directly from the definition of
176*bb4ee6a4SAndroid Build Coastguard Worker //! a bitfield struct.
177*bb4ee6a4SAndroid Build Coastguard Worker //!
178*bb4ee6a4SAndroid Build Coastguard Worker //! ```
179*bb4ee6a4SAndroid Build Coastguard Worker //! use bit_field::*;
180*bb4ee6a4SAndroid Build Coastguard Worker //!
181*bb4ee6a4SAndroid Build Coastguard Worker //! #[bitfield]
182*bb4ee6a4SAndroid Build Coastguard Worker //! #[derive(Debug, PartialEq)]
183*bb4ee6a4SAndroid Build Coastguard Worker //! enum WhoKnows {
184*bb4ee6a4SAndroid Build Coastguard Worker //! Zero = 0b00,
185*bb4ee6a4SAndroid Build Coastguard Worker //! One = 0b01,
186*bb4ee6a4SAndroid Build Coastguard Worker //! Two = 0b10,
187*bb4ee6a4SAndroid Build Coastguard Worker //! Three = 0b11,
188*bb4ee6a4SAndroid Build Coastguard Worker //! }
189*bb4ee6a4SAndroid Build Coastguard Worker //!
190*bb4ee6a4SAndroid Build Coastguard Worker //! #[bitfield]
191*bb4ee6a4SAndroid Build Coastguard Worker //! struct Struct {
192*bb4ee6a4SAndroid Build Coastguard Worker //! prefix: BitField1,
193*bb4ee6a4SAndroid Build Coastguard Worker //! #[bits = 2]
194*bb4ee6a4SAndroid Build Coastguard Worker //! two_bits: WhoKnows,
195*bb4ee6a4SAndroid Build Coastguard Worker //! suffix: BitField5,
196*bb4ee6a4SAndroid Build Coastguard Worker //! }
197*bb4ee6a4SAndroid Build Coastguard Worker //! ```
198*bb4ee6a4SAndroid Build Coastguard Worker //!
199*bb4ee6a4SAndroid Build Coastguard Worker //! # Derives
200*bb4ee6a4SAndroid Build Coastguard Worker //!
201*bb4ee6a4SAndroid Build Coastguard Worker //! Derives may be specified and are applied to the data structure post
202*bb4ee6a4SAndroid Build Coastguard Worker //! rewriting by the macro.
203*bb4ee6a4SAndroid Build Coastguard Worker //!
204*bb4ee6a4SAndroid Build Coastguard Worker //! ```
205*bb4ee6a4SAndroid Build Coastguard Worker //! use bit_field::*;
206*bb4ee6a4SAndroid Build Coastguard Worker //!
207*bb4ee6a4SAndroid Build Coastguard Worker //! #[bitfield]
208*bb4ee6a4SAndroid Build Coastguard Worker //! #[derive(Copy, Clone)]
209*bb4ee6a4SAndroid Build Coastguard Worker //! pub struct ExampleWithDerives {
210*bb4ee6a4SAndroid Build Coastguard Worker //! car: B4,
211*bb4ee6a4SAndroid Build Coastguard Worker //! cdr: B4,
212*bb4ee6a4SAndroid Build Coastguard Worker //! }
213*bb4ee6a4SAndroid Build Coastguard Worker //! ```
214*bb4ee6a4SAndroid Build Coastguard Worker //!
215*bb4ee6a4SAndroid Build Coastguard Worker //! # Compile time checks
216*bb4ee6a4SAndroid Build Coastguard Worker //!
217*bb4ee6a4SAndroid Build Coastguard Worker //! If the total size is not a multiple of 8 bits, you will receive an error
218*bb4ee6a4SAndroid Build Coastguard Worker //! message at compile time mentioning:
219*bb4ee6a4SAndroid Build Coastguard Worker //!
220*bb4ee6a4SAndroid Build Coastguard Worker //! > the trait `bit_field::checks::TotalSizeIsMultipleOfEightBits` is not implemented
221*bb4ee6a4SAndroid Build Coastguard Worker //!
222*bb4ee6a4SAndroid Build Coastguard Worker //! ```compile_fail
223*bb4ee6a4SAndroid Build Coastguard Worker //! use bit_field::*;
224*bb4ee6a4SAndroid Build Coastguard Worker //!
225*bb4ee6a4SAndroid Build Coastguard Worker //! #[bitfield]
226*bb4ee6a4SAndroid Build Coastguard Worker //! pub struct Broken {
227*bb4ee6a4SAndroid Build Coastguard Worker //! field_a: B1,
228*bb4ee6a4SAndroid Build Coastguard Worker //! field_b: B3,
229*bb4ee6a4SAndroid Build Coastguard Worker //! field_c: B6,
230*bb4ee6a4SAndroid Build Coastguard Worker //! }
231*bb4ee6a4SAndroid Build Coastguard Worker //! ```
232*bb4ee6a4SAndroid Build Coastguard Worker //!
233*bb4ee6a4SAndroid Build Coastguard Worker //! If a bitfield enum has discriminants that are outside the range 0 through
234*bb4ee6a4SAndroid Build Coastguard Worker //! (2^n)-1, it will be caught at compile time.
235*bb4ee6a4SAndroid Build Coastguard Worker //!
236*bb4ee6a4SAndroid Build Coastguard Worker //! ```compile_fail
237*bb4ee6a4SAndroid Build Coastguard Worker //! use bit_field::*;
238*bb4ee6a4SAndroid Build Coastguard Worker //!
239*bb4ee6a4SAndroid Build Coastguard Worker //! #[bitfield]
240*bb4ee6a4SAndroid Build Coastguard Worker //! enum Broken {
241*bb4ee6a4SAndroid Build Coastguard Worker //! Zero = 0b00,
242*bb4ee6a4SAndroid Build Coastguard Worker //! One = 0b01,
243*bb4ee6a4SAndroid Build Coastguard Worker //! Two = 0b10,
244*bb4ee6a4SAndroid Build Coastguard Worker //! Nine = 0b1001, // error
245*bb4ee6a4SAndroid Build Coastguard Worker //! }
246*bb4ee6a4SAndroid Build Coastguard Worker //! ```
247*bb4ee6a4SAndroid Build Coastguard Worker //!
248*bb4ee6a4SAndroid Build Coastguard Worker //! If the value provided in a #[bits = N] attribute does not match the real
249*bb4ee6a4SAndroid Build Coastguard Worker //! number of bits in that field, it will be caught.
250*bb4ee6a4SAndroid Build Coastguard Worker //!
251*bb4ee6a4SAndroid Build Coastguard Worker //! ```compile_fail
252*bb4ee6a4SAndroid Build Coastguard Worker //! use bit_field::*;
253*bb4ee6a4SAndroid Build Coastguard Worker //!
254*bb4ee6a4SAndroid Build Coastguard Worker //! #[bitfield]
255*bb4ee6a4SAndroid Build Coastguard Worker //! #[derive(Debug, PartialEq)]
256*bb4ee6a4SAndroid Build Coastguard Worker //! enum OneBit {
257*bb4ee6a4SAndroid Build Coastguard Worker //! No = 0,
258*bb4ee6a4SAndroid Build Coastguard Worker //! Yes = 1,
259*bb4ee6a4SAndroid Build Coastguard Worker //! }
260*bb4ee6a4SAndroid Build Coastguard Worker //!
261*bb4ee6a4SAndroid Build Coastguard Worker //! #[bitfield]
262*bb4ee6a4SAndroid Build Coastguard Worker //! struct Struct {
263*bb4ee6a4SAndroid Build Coastguard Worker //! #[bits = 4] // error
264*bb4ee6a4SAndroid Build Coastguard Worker //! two_bits: OneBit,
265*bb4ee6a4SAndroid Build Coastguard Worker //! padding: BitField7,
266*bb4ee6a4SAndroid Build Coastguard Worker //! }
267*bb4ee6a4SAndroid Build Coastguard Worker //! ```
268*bb4ee6a4SAndroid Build Coastguard Worker
269*bb4ee6a4SAndroid Build Coastguard Worker use std::fmt;
270*bb4ee6a4SAndroid Build Coastguard Worker use std::fmt::Display;
271*bb4ee6a4SAndroid Build Coastguard Worker
272*bb4ee6a4SAndroid Build Coastguard Worker pub use bit_field_derive::bitfield;
273*bb4ee6a4SAndroid Build Coastguard Worker
274*bb4ee6a4SAndroid Build Coastguard Worker /// Error type for bit field get.
275*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Debug)]
276*bb4ee6a4SAndroid Build Coastguard Worker pub struct Error {
277*bb4ee6a4SAndroid Build Coastguard Worker type_name: &'static str,
278*bb4ee6a4SAndroid Build Coastguard Worker val: u64,
279*bb4ee6a4SAndroid Build Coastguard Worker }
280*bb4ee6a4SAndroid Build Coastguard Worker
281*bb4ee6a4SAndroid Build Coastguard Worker impl Error {
new(type_name: &'static str, val: u64) -> Error282*bb4ee6a4SAndroid Build Coastguard Worker pub fn new(type_name: &'static str, val: u64) -> Error {
283*bb4ee6a4SAndroid Build Coastguard Worker Error { type_name, val }
284*bb4ee6a4SAndroid Build Coastguard Worker }
285*bb4ee6a4SAndroid Build Coastguard Worker
raw_val(&self) -> u64286*bb4ee6a4SAndroid Build Coastguard Worker pub fn raw_val(&self) -> u64 {
287*bb4ee6a4SAndroid Build Coastguard Worker self.val
288*bb4ee6a4SAndroid Build Coastguard Worker }
289*bb4ee6a4SAndroid Build Coastguard Worker }
290*bb4ee6a4SAndroid Build Coastguard Worker
291*bb4ee6a4SAndroid Build Coastguard Worker impl Display for Error {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result292*bb4ee6a4SAndroid Build Coastguard Worker fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
293*bb4ee6a4SAndroid Build Coastguard Worker write!(
294*bb4ee6a4SAndroid Build Coastguard Worker f,
295*bb4ee6a4SAndroid Build Coastguard Worker "enum field type {} has a bad value {}",
296*bb4ee6a4SAndroid Build Coastguard Worker self.type_name, self.val
297*bb4ee6a4SAndroid Build Coastguard Worker )
298*bb4ee6a4SAndroid Build Coastguard Worker }
299*bb4ee6a4SAndroid Build Coastguard Worker }
300*bb4ee6a4SAndroid Build Coastguard Worker
301*bb4ee6a4SAndroid Build Coastguard Worker impl std::error::Error for Error {}
302*bb4ee6a4SAndroid Build Coastguard Worker
303*bb4ee6a4SAndroid Build Coastguard Worker #[doc(hidden)]
304*bb4ee6a4SAndroid Build Coastguard Worker pub trait BitFieldSpecifier {
305*bb4ee6a4SAndroid Build Coastguard Worker // Width of this field in bits.
306*bb4ee6a4SAndroid Build Coastguard Worker const FIELD_WIDTH: u8;
307*bb4ee6a4SAndroid Build Coastguard Worker // Date type for setter of this field.
308*bb4ee6a4SAndroid Build Coastguard Worker // For any field, we use the closest u* type. e.g. FIELD_WIDTH <= 8 will
309*bb4ee6a4SAndroid Build Coastguard Worker // have defulat type of u8.
310*bb4ee6a4SAndroid Build Coastguard Worker // It's possible to write a custom specifier and use i8.
311*bb4ee6a4SAndroid Build Coastguard Worker type SetterType;
312*bb4ee6a4SAndroid Build Coastguard Worker // Data type for getter of this field. For enums, it will be Result<EnumType, SetterType>.
313*bb4ee6a4SAndroid Build Coastguard Worker // For others, it will be the same as SetterType.
314*bb4ee6a4SAndroid Build Coastguard Worker type GetterType;
315*bb4ee6a4SAndroid Build Coastguard Worker
from_u64(val: u64) -> Self::GetterType316*bb4ee6a4SAndroid Build Coastguard Worker fn from_u64(val: u64) -> Self::GetterType;
into_u64(val: Self::SetterType) -> u64317*bb4ee6a4SAndroid Build Coastguard Worker fn into_u64(val: Self::SetterType) -> u64;
318*bb4ee6a4SAndroid Build Coastguard Worker }
319*bb4ee6a4SAndroid Build Coastguard Worker
320*bb4ee6a4SAndroid Build Coastguard Worker // Largest u64 representable by this bit field specifier. Used by generated code
321*bb4ee6a4SAndroid Build Coastguard Worker // in bit_field_derive.
322*bb4ee6a4SAndroid Build Coastguard Worker #[doc(hidden)]
323*bb4ee6a4SAndroid Build Coastguard Worker #[inline]
max<T: BitFieldSpecifier>() -> u64324*bb4ee6a4SAndroid Build Coastguard Worker pub fn max<T: BitFieldSpecifier>() -> u64 {
325*bb4ee6a4SAndroid Build Coastguard Worker if T::FIELD_WIDTH < 64 {
326*bb4ee6a4SAndroid Build Coastguard Worker (1 << T::FIELD_WIDTH) - 1
327*bb4ee6a4SAndroid Build Coastguard Worker } else {
328*bb4ee6a4SAndroid Build Coastguard Worker u64::MAX
329*bb4ee6a4SAndroid Build Coastguard Worker }
330*bb4ee6a4SAndroid Build Coastguard Worker }
331*bb4ee6a4SAndroid Build Coastguard Worker
332*bb4ee6a4SAndroid Build Coastguard Worker // Defines bit_field::BitField0 through bit_field::BitField64.
333*bb4ee6a4SAndroid Build Coastguard Worker bit_field_derive::define_bit_field_specifiers!();
334*bb4ee6a4SAndroid Build Coastguard Worker
335*bb4ee6a4SAndroid Build Coastguard Worker impl BitFieldSpecifier for bool {
336*bb4ee6a4SAndroid Build Coastguard Worker const FIELD_WIDTH: u8 = 1;
337*bb4ee6a4SAndroid Build Coastguard Worker type SetterType = bool;
338*bb4ee6a4SAndroid Build Coastguard Worker type GetterType = bool;
339*bb4ee6a4SAndroid Build Coastguard Worker
340*bb4ee6a4SAndroid Build Coastguard Worker #[inline]
from_u64(val: u64) -> Self::GetterType341*bb4ee6a4SAndroid Build Coastguard Worker fn from_u64(val: u64) -> Self::GetterType {
342*bb4ee6a4SAndroid Build Coastguard Worker val > 0
343*bb4ee6a4SAndroid Build Coastguard Worker }
344*bb4ee6a4SAndroid Build Coastguard Worker
345*bb4ee6a4SAndroid Build Coastguard Worker #[inline]
into_u64(val: Self::SetterType) -> u64346*bb4ee6a4SAndroid Build Coastguard Worker fn into_u64(val: Self::SetterType) -> u64 {
347*bb4ee6a4SAndroid Build Coastguard Worker val as u64
348*bb4ee6a4SAndroid Build Coastguard Worker }
349*bb4ee6a4SAndroid Build Coastguard Worker }
350*bb4ee6a4SAndroid Build Coastguard Worker
351*bb4ee6a4SAndroid Build Coastguard Worker // Instantiated by the generated code to prove that the total size of fields is
352*bb4ee6a4SAndroid Build Coastguard Worker // a multiple of 8 bits.
353*bb4ee6a4SAndroid Build Coastguard Worker #[doc(hidden)]
354*bb4ee6a4SAndroid Build Coastguard Worker pub struct Check<T: checks::TotalSizeIsMultipleOfEightBits> {
355*bb4ee6a4SAndroid Build Coastguard Worker marker: std::marker::PhantomData<T>,
356*bb4ee6a4SAndroid Build Coastguard Worker }
357*bb4ee6a4SAndroid Build Coastguard Worker
358*bb4ee6a4SAndroid Build Coastguard Worker mod checks {
359*bb4ee6a4SAndroid Build Coastguard Worker pub trait TotalSizeIsMultipleOfEightBits {}
360*bb4ee6a4SAndroid Build Coastguard Worker impl TotalSizeIsMultipleOfEightBits for [u8; 0] {}
361*bb4ee6a4SAndroid Build Coastguard Worker }
362