diff --git a/src/parser.rs b/src/parser.rs index f322f71..4374ddb 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,17 +1,19 @@ use proc_macro::{Span, TokenStream}; use syn::{ - Error, Result, - Ident, ItemEnum, Token, parse::{Parse, ParseStream}, punctuated::Punctuated, + Error, Ident, ItemEnum, Result, Token, }; pub fn parse(attr: TokenStream, mut item: ItemEnum) -> Result { let typ = parse_typ(attr)?; - let config = if let Some(idx) = item.attrs.iter().enumerate().find_map( - |(idx, attr)| attr.path().is_ident("bitmask_config").then_some(idx) - ) { + let config = if let Some(idx) = item + .attrs + .iter() + .enumerate() + .find_map(|(idx, attr)| attr.path().is_ident("bitmask_config").then_some(idx)) + { item.attrs.remove(idx).parse_args::()? } else { Config::new() @@ -47,17 +49,20 @@ pub fn parse(attr: TokenStream, mut item: ItemEnum) -> Result { expr }; - let i_flag = config.inverted_flags.then(|| { - let i_ident = Ident::new(&format!("Inverted{}", v_ident), v_ident.span()); + let i_flag = config + .inverted_flags + .then(|| { + let i_ident = Ident::new(&format!("Inverted{}", v_ident), v_ident.span()); - all_flags.push(quote::quote!(Self::#i_ident)); - all_flags_names.push(quote::quote!(stringify!(#i_ident))); + all_flags.push(quote::quote!(Self::#i_ident)); + all_flags_names.push(quote::quote!(stringify!(#i_ident))); - quote::quote!( - #(#v_attrs)* - #vis const #i_ident: #ident = Self { bits: (#expr) ^ !0 }; - ) - }).into_iter(); + quote::quote!( + #(#v_attrs)* + #vis const #i_ident: #ident = Self { bits: (#expr) ^ !0 }; + ) + }) + .into_iter(); flags.push(quote::quote!( #(#v_attrs)* @@ -81,7 +86,7 @@ pub fn parse(attr: TokenStream, mut item: ItemEnum) -> Result { } } } - } else { + } else { quote::quote! { impl core::fmt::Debug for #ident { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { @@ -208,7 +213,7 @@ pub fn parse(attr: TokenStream, mut item: ItemEnum) -> Result { type Output = Self; #[inline] fn not(self) -> Self::Output { - Self { bits: self.bits.not() } + Self { bits: core::ops::Not::not(self.bits) } } } @@ -216,14 +221,14 @@ pub fn parse(attr: TokenStream, mut item: ItemEnum) -> Result { type Output = Self; #[inline] fn bitand(self, rhs: Self) -> Self::Output { - Self { bits: self.bits.bitand(rhs.bits) } + Self { bits: core::ops::BitAnd::bitand(self.bits, rhs.bits) } } } impl core::ops::BitAndAssign for #ident { #[inline] - fn bitand_assign(&mut self, rhs: Self){ - self.bits.bitand_assign(rhs.bits) + fn bitand_assign(&mut self, rhs: Self) { + core::ops::BitAndAssign::bitand_assign(&mut self.bits, rhs.bits) } } @@ -231,14 +236,14 @@ pub fn parse(attr: TokenStream, mut item: ItemEnum) -> Result { type Output = Self; #[inline] fn bitor(self, rhs: Self) -> Self::Output { - Self { bits: self.bits.bitor(rhs.bits) } + Self { bits: core::ops::BitOr::bitor(self.bits, rhs.bits) } } } impl core::ops::BitOrAssign for #ident { #[inline] - fn bitor_assign(&mut self, rhs: Self){ - self.bits.bitor_assign(rhs.bits) + fn bitor_assign(&mut self, rhs: Self) { + core::ops::BitOrAssign::bitor_assign(&mut self.bits, rhs.bits) } } @@ -246,14 +251,14 @@ pub fn parse(attr: TokenStream, mut item: ItemEnum) -> Result { type Output = Self; #[inline] fn bitxor(self, rhs: Self) -> Self::Output { - Self { bits: self.bits.bitxor(rhs.bits) } + Self { bits: core::ops::BitXor::bitxor(self.bits, rhs.bits) } } } impl core::ops::BitXorAssign for #ident { #[inline] - fn bitxor_assign(&mut self, rhs: Self){ - self.bits.bitxor_assign(rhs.bits) + fn bitxor_assign(&mut self, rhs: Self) { + core::ops::BitXorAssign::bitxor_assign(&mut self.bits, rhs.bits) } } @@ -283,28 +288,28 @@ pub fn parse(attr: TokenStream, mut item: ItemEnum) -> Result { impl core::fmt::Binary for #ident { #[inline] fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - self.bits.fmt(f) + core::fmt::Binary::fmt(&self.bits, f) } } impl core::fmt::LowerHex for #ident { #[inline] fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - self.bits.fmt(f) + core::fmt::LowerHex::fmt(&self.bits, f) } } impl core::fmt::UpperHex for #ident { #[inline] fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - self.bits.fmt(f) + core::fmt::UpperHex::fmt(&self.bits, f) } } impl core::fmt::Octal for #ident { #[inline] fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - self.bits.fmt(f) + core::fmt::Octal::fmt(&self.bits, f) } } })) @@ -319,21 +324,24 @@ fn parse_typ(attr: TokenStream) -> Result { #[rustfmt::skip] "u8" | "u16" | "u32" | "u64" | "u128" | "usize" | "i8" | "i16" | "i32" | "i64" | "i128" | "isize" => Ok(ident), - _ => Err(Error::new_spanned(ident, "type can only be an (un)signed integer")), + _ => Err(Error::new_spanned( + ident, + "type can only be an (un)signed integer", + )), } } } struct Config { inverted_flags: bool, - vec_debug: bool + vec_debug: bool, } impl Config { fn new() -> Self { Self { inverted_flags: false, - vec_debug: false + vec_debug: false, } } } diff --git a/tests/tests.rs b/tests/tests.rs index 5ef98f7..6b5cac7 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -56,7 +56,17 @@ mod tests { fn test_full() { let full = Bitmask::full(); assert_eq!(full.is_full(), true); - assert_eq!(full, Bitmask::Flag1 | Bitmask::Flag2 | Bitmask::Flag3 | Bitmask::Flag4 | Bitmask::Flag5 | Bitmask::Flag6 | Bitmask::Flag7 | Bitmask::Flag8); + assert_eq!( + full, + Bitmask::Flag1 + | Bitmask::Flag2 + | Bitmask::Flag3 + | Bitmask::Flag4 + | Bitmask::Flag5 + | Bitmask::Flag6 + | Bitmask::Flag7 + | Bitmask::Flag8 + ); } #[test] @@ -347,19 +357,43 @@ mod tests { Flag3, } - assert_eq!(format!("{:?}", BitmaskVecDebug::none()), "BitmaskVecDebug[]"); - assert_eq!(format!("{:?}", BitmaskVecDebug::Flag1), "BitmaskVecDebug[Flag1]"); - assert_eq!(format!("{:?}", BitmaskVecDebug::Flag2), "BitmaskVecDebug[Flag2]"); - assert_eq!(format!("{:?}", BitmaskVecDebug::Flag12), "BitmaskVecDebug[Flag1, Flag2, Flag12]"); - assert_eq!(format!("{:?}", BitmaskVecDebug::Flag3), "BitmaskVecDebug[Flag3]"); - assert_eq!(format!("{:?}", BitmaskVecDebug::Flag2.or(BitmaskVecDebug::Flag3)), "BitmaskVecDebug[Flag2, Flag3]"); - assert_eq!(format!("{:?}", BitmaskVecDebug::full()), "BitmaskVecDebug[Flag1, Flag2, Flag12, Flag3]"); + assert_eq!( + format!("{:?}", BitmaskVecDebug::none()), + "BitmaskVecDebug[]" + ); + assert_eq!( + format!("{:?}", BitmaskVecDebug::Flag1), + "BitmaskVecDebug[Flag1]" + ); + assert_eq!( + format!("{:?}", BitmaskVecDebug::Flag2), + "BitmaskVecDebug[Flag2]" + ); + assert_eq!( + format!("{:?}", BitmaskVecDebug::Flag12), + "BitmaskVecDebug[Flag1, Flag2, Flag12]" + ); + assert_eq!( + format!("{:?}", BitmaskVecDebug::Flag3), + "BitmaskVecDebug[Flag3]" + ); + assert_eq!( + format!("{:?}", BitmaskVecDebug::Flag2.or(BitmaskVecDebug::Flag3)), + "BitmaskVecDebug[Flag2, Flag3]" + ); + assert_eq!( + format!("{:?}", BitmaskVecDebug::full()), + "BitmaskVecDebug[Flag1, Flag2, Flag12, Flag3]" + ); // default formatting assert_eq!(format!("{:?}", Bitmask::none()), "Bitmask { bits: 0 }"); assert_eq!(format!("{:?}", Bitmask::Flag1), "Bitmask { bits: 1 }"); assert_eq!(format!("{:?}", Bitmask::Flag2), "Bitmask { bits: 2 }"); - assert_eq!(format!("{:?}", Bitmask::Flag1.or(Bitmask::Flag2)), "Bitmask { bits: 3 }"); + assert_eq!( + format!("{:?}", Bitmask::Flag1.or(Bitmask::Flag2)), + "Bitmask { bits: 3 }" + ); assert_eq!(format!("{:?}", Bitmask::Flag3), "Bitmask { bits: 4 }"); } @@ -369,14 +403,46 @@ mod tests { #[bitmask_config(vec_debug, inverted_flags)] pub enum BitmaskVecDebug { Flag1, - Flag2 + Flag2, } - assert_eq!(format!("{:?}", BitmaskVecDebug::none()), "BitmaskVecDebug[]"); - assert_eq!(format!("{:?}", BitmaskVecDebug::Flag1), "BitmaskVecDebug[Flag1]"); - assert_eq!(format!("{:?}", BitmaskVecDebug::Flag2), "BitmaskVecDebug[Flag2]"); - assert_eq!(format!("{:?}", BitmaskVecDebug::InvertedFlag1), "BitmaskVecDebug[InvertedFlag1, Flag2]"); - assert_eq!(format!("{:?}", BitmaskVecDebug::InvertedFlag2), "BitmaskVecDebug[Flag1, InvertedFlag2]"); - assert_eq!(format!("{:?}", BitmaskVecDebug::full()), "BitmaskVecDebug[Flag1, InvertedFlag1, Flag2, InvertedFlag2]"); + assert_eq!( + format!("{:?}", BitmaskVecDebug::none()), + "BitmaskVecDebug[]" + ); + assert_eq!( + format!("{:?}", BitmaskVecDebug::Flag1), + "BitmaskVecDebug[Flag1]" + ); + assert_eq!( + format!("{:?}", BitmaskVecDebug::Flag2), + "BitmaskVecDebug[Flag2]" + ); + assert_eq!( + format!("{:?}", BitmaskVecDebug::InvertedFlag1), + "BitmaskVecDebug[InvertedFlag1, Flag2]" + ); + assert_eq!( + format!("{:?}", BitmaskVecDebug::InvertedFlag2), + "BitmaskVecDebug[Flag1, InvertedFlag2]" + ); + assert_eq!( + format!("{:?}", BitmaskVecDebug::full()), + "BitmaskVecDebug[Flag1, InvertedFlag1, Flag2, InvertedFlag2]" + ); + } + + #[test] + fn test_import_debug() { + // check that having a `Debug` import doesn't lead to a conflict + #[allow(unused)] + use std::fmt::Debug; + + // this should just compile + #[bitmask] + pub enum BitmaskImportDebug { + Flag1, + Flag2, + } } }