|
44 | 44 | //! ## Optional Feature Flags
|
45 | 45 | //!
|
46 | 46 | //! - [`serde`](https://serde.rs/) implements `Serialize` and `Deserialize` for `BitFlags<T>`.
|
| 47 | +//! - `std` implements `std::error::Error` for `FromBitsError`. |
47 | 48 | #![warn(missing_docs)]
|
48 |
| -#![cfg_attr(not(test), no_std)] |
| 49 | +#![cfg_attr(all(not(test), not(feature = "std")), no_std)] |
49 | 50 |
|
50 |
| -#[cfg(test)] |
| 51 | +#[cfg(all(test, not(feature = "std")))] |
51 | 52 | extern crate core;
|
52 | 53 | use core::{cmp, ops};
|
53 | 54 | use core::iter::FromIterator;
|
@@ -118,6 +119,9 @@ pub mod _internal {
|
118 | 119 | // Internal debug formatting implementations
|
119 | 120 | mod formatting;
|
120 | 121 |
|
| 122 | +// impl TryFrom<T::Type> for BitFlags<T> |
| 123 | +mod fallible; |
| 124 | + |
121 | 125 | use _internal::RawBitFlags;
|
122 | 126 |
|
123 | 127 | /// Represents a set of flags of some type `T`.
|
@@ -150,7 +154,7 @@ where
|
150 | 154 |
|
151 | 155 | impl<T: RawBitFlags> From<T> for BitFlags<T> {
|
152 | 156 | fn from(t: T) -> BitFlags<T> {
|
153 |
| - BitFlags { val: t.bits() } |
| 157 | + Self::from_flag(t) |
154 | 158 | }
|
155 | 159 | }
|
156 | 160 |
|
@@ -203,6 +207,22 @@ where
|
203 | 207 | }
|
204 | 208 | }
|
205 | 209 |
|
| 210 | + pub fn from_flag(t: T) -> Self { |
| 211 | + BitFlags { val: t.bits() } |
| 212 | + } |
| 213 | + |
| 214 | + pub fn try_from_bits(bits: T::Type) -> Result<Self, FromBitsError<T>> { |
| 215 | + let flags = Self::from_bits_truncate(bits); |
| 216 | + if flags.bits() == bits { |
| 217 | + Ok(flags) |
| 218 | + } else { |
| 219 | + Err(FromBitsError { |
| 220 | + flags, |
| 221 | + invalid: bits & !flags.bits(), |
| 222 | + }) |
| 223 | + } |
| 224 | + } |
| 225 | + |
206 | 226 | /// Truncates flags that are illegal
|
207 | 227 | pub fn from_bits_truncate(bits: T::Type) -> Self {
|
208 | 228 | unsafe { BitFlags::new(bits & T::all()) }
|
@@ -360,3 +380,26 @@ mod impl_serde {
|
360 | 380 | }
|
361 | 381 | }
|
362 | 382 | }
|
| 383 | + |
| 384 | +#[derive(Debug, Copy, Clone)] |
| 385 | +pub struct FromBitsError<T: RawBitFlags> { |
| 386 | + flags: BitFlags<T>, |
| 387 | + invalid: T::Type, |
| 388 | +} |
| 389 | + |
| 390 | +impl<T: RawBitFlags> FromBitsError<T> { |
| 391 | + pub fn truncate(self) -> BitFlags<T> { |
| 392 | + self.flags |
| 393 | + } |
| 394 | + |
| 395 | + pub fn invalid_bits(self) -> T::Type { |
| 396 | + self.invalid |
| 397 | + } |
| 398 | +} |
| 399 | + |
| 400 | +#[cfg(feature = "std")] |
| 401 | +impl<T: RawBitFlags> std::error::Error for FromBitsError<T> { |
| 402 | + fn description(&self) -> &str { |
| 403 | + "invalid bit representation" |
| 404 | + } |
| 405 | +} |
0 commit comments