wiggle: use bitflags to generate flags
more consistient with the rest of the ecosystem.
This commit is contained in:
@@ -27,102 +27,31 @@ pub(super) fn define_flags(names: &Names, name: &witx::Id, f: &witx::FlagsDataty
|
||||
}
|
||||
|
||||
quote! {
|
||||
#[repr(transparent)]
|
||||
#[derive(Copy, Clone, Debug, ::std::hash::Hash, Eq, PartialEq)]
|
||||
pub struct #ident(#repr);
|
||||
|
||||
impl #ident {
|
||||
#(pub const #names_: #ident = #ident(#values_);)*
|
||||
|
||||
#[inline]
|
||||
pub const fn empty() -> Self {
|
||||
#ident(0)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn all() -> Self {
|
||||
#ident(#(#values_)|*)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn contains(&self, other: &#ident) -> bool {
|
||||
!*self & *other == Self::empty()
|
||||
#rt::bitflags::bitflags! {
|
||||
pub struct #ident: #repr {
|
||||
#(const #names_ = #values_;)*
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::fmt::Display for #ident {
|
||||
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||
let mut first = true;
|
||||
#(
|
||||
if self.0 & #values_ == #values_ {
|
||||
if !first {
|
||||
f.write_str("|")?;
|
||||
}
|
||||
first = false;
|
||||
f.write_fmt(format_args!("{}", stringify!(#names_).to_lowercase()))?;
|
||||
}
|
||||
)*
|
||||
if first {
|
||||
f.write_str("empty")?;
|
||||
}
|
||||
f.write_fmt(format_args!(" ({:#x})", self.0))?;
|
||||
f.write_str(stringify!(#ident))?;
|
||||
f.write_str("(")?;
|
||||
::std::fmt::Debug::fmt(self, f)?;
|
||||
f.write_str(" (0x")?;
|
||||
::std::fmt::LowerHex::fmt(&self.bits, f)?;
|
||||
f.write_str("))")?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::BitAnd for #ident {
|
||||
type Output = Self;
|
||||
fn bitand(self, rhs: Self) -> Self::Output {
|
||||
#ident(self.0 & rhs.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::BitAndAssign for #ident {
|
||||
fn bitand_assign(&mut self, rhs: Self) {
|
||||
*self = *self & rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::BitOr for #ident {
|
||||
type Output = Self;
|
||||
fn bitor(self, rhs: Self) -> Self::Output {
|
||||
#ident(self.0 | rhs.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::BitOrAssign for #ident {
|
||||
fn bitor_assign(&mut self, rhs: Self) {
|
||||
*self = *self | rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::BitXor for #ident {
|
||||
type Output = Self;
|
||||
fn bitxor(self, rhs: Self) -> Self::Output {
|
||||
#ident(self.0 ^ rhs.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::BitXorAssign for #ident {
|
||||
fn bitxor_assign(&mut self, rhs: Self) {
|
||||
*self = *self ^ rhs
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::ops::Not for #ident {
|
||||
type Output = Self;
|
||||
fn not(self) -> Self::Output {
|
||||
#ident(!self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::convert::TryFrom<#repr> for #ident {
|
||||
type Error = #rt::GuestError;
|
||||
fn try_from(value: #repr) -> Result<Self, #rt::GuestError> {
|
||||
if #repr::from(!#ident::all()) & value != 0 {
|
||||
Err(#rt::GuestError::InvalidFlagValue(stringify!(#ident)))
|
||||
} else {
|
||||
Ok(#ident(value))
|
||||
Ok(#ident { bits: value })
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -136,7 +65,7 @@ pub(super) fn define_flags(names: &Names, name: &witx::Id, f: &witx::FlagsDataty
|
||||
|
||||
impl From<#ident> for #repr {
|
||||
fn from(e: #ident) -> #repr {
|
||||
e.0
|
||||
e.bits
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -103,11 +103,11 @@ proptest! {
|
||||
#[test]
|
||||
fn flags_fmt() {
|
||||
let empty = format!("{}", types::CarConfig::empty());
|
||||
assert_eq!(empty, "empty (0x0)");
|
||||
assert_eq!(empty, "CarConfig((empty) (0x0))");
|
||||
let one_flag = format!("{}", types::CarConfig::AWD);
|
||||
assert_eq!(one_flag, "awd (0x2)");
|
||||
assert_eq!(one_flag, "CarConfig(AWD (0x2))");
|
||||
let two_flags = format!("{}", types::CarConfig::AUTOMATIC | types::CarConfig::SUV);
|
||||
assert_eq!(two_flags, "automatic|suv (0x5)");
|
||||
assert_eq!(two_flags, "CarConfig(AUTOMATIC | SUV (0x5))");
|
||||
let all = format!("{}", types::CarConfig::all());
|
||||
assert_eq!(all, "automatic|awd|suv (0x7)");
|
||||
assert_eq!(all, "CarConfig(AUTOMATIC | AWD | SUV (0x7))");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user