From ed44a19e5ef7c0fa056b2104aee3a195c3375b2d Mon Sep 17 00:00:00 2001 From: Pat Hickey Date: Mon, 11 Jan 2021 18:20:57 -0800 Subject: [PATCH] wiggle: use bitflags to generate flags more consistient with the rest of the ecosystem. --- crates/wiggle/generate/src/types/flags.rs | 93 +++-------------------- crates/wiggle/tests/flags.rs | 8 +- 2 files changed, 15 insertions(+), 86 deletions(-) diff --git a/crates/wiggle/generate/src/types/flags.rs b/crates/wiggle/generate/src/types/flags.rs index f87261abca..cda13a2bfa 100644 --- a/crates/wiggle/generate/src/types/flags.rs +++ b/crates/wiggle/generate/src/types/flags.rs @@ -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 { 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 } } diff --git a/crates/wiggle/tests/flags.rs b/crates/wiggle/tests/flags.rs index e12b64a457..1a2bb0019f 100644 --- a/crates/wiggle/tests/flags.rs +++ b/crates/wiggle/tests/flags.rs @@ -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))"); }