maraiah: add FromStr for cbitfield
parent
68bfd417b5
commit
bb173b47e3
|
@ -1,5 +1,6 @@
|
||||||
#![doc(hidden)]
|
#![doc(hidden)]
|
||||||
|
|
||||||
|
/// A wrapper for `bitflags!` which adds a `FromStr` implementation.
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! c_bitfield
|
macro_rules! c_bitfield
|
||||||
{
|
{
|
||||||
|
@ -22,6 +23,65 @@ macro_rules! c_bitfield
|
||||||
)+
|
)+
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused_qualifications)]
|
||||||
|
impl std::str::FromStr for $t
|
||||||
|
{
|
||||||
|
type Err = $crate::err::ParseFlagError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err>
|
||||||
|
{
|
||||||
|
let mut flags = $t::empty();
|
||||||
|
|
||||||
|
for s in s.split('|') {
|
||||||
|
match s {
|
||||||
|
$(
|
||||||
|
stringify!($f) => flags.insert($t::$f),
|
||||||
|
)+
|
||||||
|
"(none)" => (),
|
||||||
|
_ => return Err(Self::Err::new(stringify!($t)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(flags)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test
|
||||||
|
{
|
||||||
|
use crate::err::ParseFlagError;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
c_bitfield! {
|
||||||
|
pub struct TestFlag: u16 {
|
||||||
|
ZERO = 0,
|
||||||
|
ONE = 1,
|
||||||
|
TWO = 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn c_bitfield()
|
||||||
|
{
|
||||||
|
assert_eq!(TestFlag::from_bits(0), Some(TestFlag::empty()));
|
||||||
|
assert_eq!(TestFlag::from_bits(1), Some(TestFlag::ZERO));
|
||||||
|
assert_eq!(TestFlag::from_bits(2), Some(TestFlag::ONE));
|
||||||
|
assert_eq!(TestFlag::from_bits(4), Some(TestFlag::TWO));
|
||||||
|
assert_eq!(TestFlag::from_bits(8), None);
|
||||||
|
assert_eq!(TestFlag::from_str("(none)"), Ok(TestFlag::empty()));
|
||||||
|
assert_eq!(TestFlag::from_str("ZERO"), Ok(TestFlag::ZERO));
|
||||||
|
assert_eq!(TestFlag::from_str("ONE"), Ok(TestFlag::ONE));
|
||||||
|
assert_eq!(TestFlag::from_str("TWO"), Ok(TestFlag::TWO));
|
||||||
|
assert_eq!(TestFlag::from_str("ZERO|ONE|TWO"), Ok(TestFlag::all()));
|
||||||
|
assert_eq!(TestFlag::from_str("TWO|ZERO|ONE"), Ok(TestFlag::all()));
|
||||||
|
assert_eq!(TestFlag::from_str("ONE|ONE|ONE"), Ok(TestFlag::ONE));
|
||||||
|
assert_eq!(TestFlag::from_str("(none)|(none)"), Ok(TestFlag::empty()));
|
||||||
|
assert_eq!(TestFlag::from_str("(none)|ONE"), Ok(TestFlag::ONE));
|
||||||
|
assert_eq!(TestFlag::from_str("THREE"),
|
||||||
|
Err(ParseFlagError::new("TestFlag")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,9 @@ macro_rules! c_enum
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err>
|
fn from_str(s: &str) -> Result<Self, Self::Err>
|
||||||
{
|
{
|
||||||
match s {
|
match s {
|
||||||
$(stringify!($en) => Ok($t::$en),)+
|
$(
|
||||||
|
stringify!($en) => Ok($t::$en),
|
||||||
|
)+
|
||||||
_ => Err(Self::Err::new(stringify!($t)))
|
_ => Err(Self::Err::new(stringify!($t)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,24 @@ impl ParseEnumError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ParseFlagError
|
||||||
|
{
|
||||||
|
/// Returns an `Error` with a message for flag parsing errata.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use maraiah::err::ParseFlagError;
|
||||||
|
///
|
||||||
|
/// assert_eq!(format!("{}", ParseFlagError::new("TypeName")),
|
||||||
|
/// "could not parse TypeName");
|
||||||
|
/// ```
|
||||||
|
pub fn new(t: &'static str) -> Self
|
||||||
|
{
|
||||||
|
Self(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ReprError
|
impl ReprError
|
||||||
{
|
{
|
||||||
/// Returns an `Error` with a message for representation errata.
|
/// Returns an `Error` with a message for representation errata.
|
||||||
|
@ -91,6 +109,7 @@ impl ReprError
|
||||||
|
|
||||||
impl Fail for ErrMsg {}
|
impl Fail for ErrMsg {}
|
||||||
impl Fail for ParseEnumError {}
|
impl Fail for ParseEnumError {}
|
||||||
|
impl Fail for ParseFlagError {}
|
||||||
impl Fail for ReprError {}
|
impl Fail for ReprError {}
|
||||||
|
|
||||||
impl fmt::Display for ParseEnumError
|
impl fmt::Display for ParseEnumError
|
||||||
|
@ -101,6 +120,14 @@ impl fmt::Display for ParseEnumError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for ParseFlagError
|
||||||
|
{
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
||||||
|
{
|
||||||
|
write!(f, "could not parse {}", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for ReprError
|
impl fmt::Display for ReprError
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
|
||||||
|
@ -124,6 +151,10 @@ struct ErrMsg(&'static str);
|
||||||
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||||
pub struct ParseEnumError(&'static str);
|
pub struct ParseEnumError(&'static str);
|
||||||
|
|
||||||
|
/// A parser error for a bit field.
|
||||||
|
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||||
|
pub struct ParseFlagError(&'static str);
|
||||||
|
|
||||||
/// A representation error for an integer.
|
/// A representation error for an integer.
|
||||||
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||||
pub struct ReprError(&'static str, i64);
|
pub struct ReprError(&'static str, i64);
|
||||||
|
|
Loading…
Reference in New Issue