summary refs log tree commit diff
path: root/bit_field/src/lib.rs
diff options
context:
space:
mode:
authorJingkui Wang <jkwang@google.com>2019-03-18 15:51:13 -0700
committerchrome-bot <chrome-bot@chromium.org>2019-03-28 19:04:03 -0700
commit85fa41f7b2b74fafa15660de09b6d20e4341be8b (patch)
tree4b457ee4a4492990463ecfb585be89f9c6c22a94 /bit_field/src/lib.rs
parentca224cd547568623dc2479c8cfaca43b091c7650 (diff)
downloadcrosvm-85fa41f7b2b74fafa15660de09b6d20e4341be8b.tar
crosvm-85fa41f7b2b74fafa15660de09b6d20e4341be8b.tar.gz
crosvm-85fa41f7b2b74fafa15660de09b6d20e4341be8b.tar.bz2
crosvm-85fa41f7b2b74fafa15660de09b6d20e4341be8b.tar.lz
crosvm-85fa41f7b2b74fafa15660de09b6d20e4341be8b.tar.xz
crosvm-85fa41f7b2b74fafa15660de09b6d20e4341be8b.tar.zst
crosvm-85fa41f7b2b74fafa15660de09b6d20e4341be8b.zip
implement bitfield for enum with a width
If we know the width of an enum type, we don't need 'power of 2' number
of variants.

BUG=None
TEST=cargo test

Change-Id: I8148b28f86bb8e4fd4f67d8a6382fc713dad1439
Reviewed-on: https://chromium-review.googlesource.com/1530455
Commit-Ready: Jingkui Wang <jkwang@google.com>
Tested-by: Jingkui Wang <jkwang@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: David Tolnay <dtolnay@chromium.org>
Diffstat (limited to 'bit_field/src/lib.rs')
-rw-r--r--bit_field/src/lib.rs63
1 files changed, 61 insertions, 2 deletions
diff --git a/bit_field/src/lib.rs b/bit_field/src/lib.rs
index cafee38..64a309b 100644
--- a/bit_field/src/lib.rs
+++ b/bit_field/src/lib.rs
@@ -101,8 +101,36 @@
 //! }
 //! ```
 //!
-//! Finally, fields may be of user-defined enum types where the enum has a
-//! number of variants which is a power of 2 and the discriminant values
+//! Finally, fields may be of user-defined enum types. The enum must satisfy one of the following
+//! requirements.
+//!
+//! The enum has `#[bits = N]` attributes with it. `N` will be the width of the field. The getter
+//! function of this enum field will return `Result<EnumType, u64>`. Raw value that does not match
+//! any variant will result in an `Err(u64)`.
+//!
+//! ```
+//! extern crate bit_field;
+//!
+//! use bit_field::*;
+//!
+//! #[bitfield]
+//! #[bits = 2]
+//! #[derive(Debug, PartialEq)]
+//! enum TwoBits {
+//!     Zero = 0b00,
+//!     One = 0b01,
+//!     Three = 0b11,
+//! }
+//!
+//! #[bitfield]
+//! struct Struct {
+//!     prefix: BitField1,
+//!     two_bits: TwoBits,
+//!     suffix: BitField5,
+//! }
+//! ```
+//!
+//! The enum has a number of variants which is a power of 2 and the discriminant values
 //! (explicit or implicit) are 0 through (2^n)-1. In this case the generated
 //! getter and setter are defined in terms of the given enum type.
 //!
@@ -235,12 +263,43 @@
 //! }
 //! ```
 
+use std::fmt::{self, Display};
+
 #[allow(unused_imports)]
 #[macro_use]
 extern crate bit_field_derive;
 
 pub use bit_field_derive::bitfield;
 
+/// Error type for bit field get.
+#[derive(Debug)]
+pub struct Error {
+    type_name: &'static str,
+    val: u64,
+}
+
+impl Error {
+    pub fn new(type_name: &'static str, val: u64) -> Error {
+        Error { type_name, val }
+    }
+
+    pub fn raw_val(&self) -> u64 {
+        self.val
+    }
+}
+
+impl Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(
+            f,
+            "enum field type {} has a bad value {}",
+            self.type_name, self.val
+        )
+    }
+}
+
+impl std::error::Error for Error {}
+
 #[doc(hidden)]
 pub trait BitFieldSpecifier {
     // Width of this field in bits.