|
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;
|
@@ -119,6 +120,9 @@ pub mod _internal {
|
119 | 120 | // Internal debug formatting implementations
|
120 | 121 | mod formatting;
|
121 | 122 |
|
| 123 | +// impl TryFrom<T::Type> for BitFlags<T> |
| 124 | +mod fallible; |
| 125 | + |
122 | 126 | use _internal::RawBitFlags;
|
123 | 127 |
|
124 | 128 | /// Represents a set of flags of some type `T`.
|
@@ -151,7 +155,7 @@ where
|
151 | 155 |
|
152 | 156 | impl<T: RawBitFlags> From<T> for BitFlags<T> {
|
153 | 157 | fn from(t: T) -> BitFlags<T> {
|
154 |
| - BitFlags { val: t.bits() } |
| 158 | + Self::from_flag(t) |
155 | 159 | }
|
156 | 160 | }
|
157 | 161 |
|
@@ -204,6 +208,22 @@ where
|
204 | 208 | }
|
205 | 209 | }
|
206 | 210 |
|
| 211 | + pub fn from_flag(t: T) -> Self { |
| 212 | + BitFlags { val: t.bits() } |
| 213 | + } |
| 214 | + |
| 215 | + pub fn try_from_bits(bits: T::Type) -> Result<Self, FromBitsError<T>> { |
| 216 | + let flags = Self::from_bits_truncate(bits); |
| 217 | + if flags.bits() == bits { |
| 218 | + Ok(flags) |
| 219 | + } else { |
| 220 | + Err(FromBitsError { |
| 221 | + flags, |
| 222 | + invalid: bits & !flags.bits(), |
| 223 | + }) |
| 224 | + } |
| 225 | + } |
| 226 | + |
207 | 227 | /// Truncates flags that are illegal
|
208 | 228 | pub fn from_bits_truncate(bits: T::Type) -> Self {
|
209 | 229 | unsafe { BitFlags::new(bits & T::all()) }
|
@@ -361,3 +381,26 @@ mod impl_serde {
|
361 | 381 | }
|
362 | 382 | }
|
363 | 383 | }
|
| 384 | + |
| 385 | +#[derive(Debug, Copy, Clone)] |
| 386 | +pub struct FromBitsError<T: RawBitFlags> { |
| 387 | + flags: BitFlags<T>, |
| 388 | + invalid: T::Type, |
| 389 | +} |
| 390 | + |
| 391 | +impl<T: RawBitFlags> FromBitsError<T> { |
| 392 | + pub fn truncate(self) -> BitFlags<T> { |
| 393 | + self.flags |
| 394 | + } |
| 395 | + |
| 396 | + pub fn invalid_bits(self) -> T::Type { |
| 397 | + self.invalid |
| 398 | + } |
| 399 | +} |
| 400 | + |
| 401 | +#[cfg(feature = "std")] |
| 402 | +impl<T: RawBitFlags> std::error::Error for FromBitsError<T> { |
| 403 | + fn description(&self) -> &str { |
| 404 | + "invalid bit representation" |
| 405 | + } |
| 406 | +} |
0 commit comments