Skip to content

Commit

Permalink
added ::full(), .is_full(), .truncate() #9
Browse files Browse the repository at this point in the history
  • Loading branch information
Lukas3674 committed Aug 12, 2023
1 parent 22e52e6 commit 9b19fdf
Showing 1 changed file with 40 additions and 0 deletions.
40 changes: 40 additions & 0 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,21 @@ pub fn parse(attr: TokenStream, mut item: ItemEnum) -> Result<TokenStream> {
let attrs = item.attrs;
let ident = item.ident;

let mut flags_amount = item.variants.len();

if config.inverted_flags {
flags_amount *= 2;
}

let mut all_flags = Vec::with_capacity(flags_amount);

let mut i: usize = 0;
let flags = item.variants.iter().map(|v| {
let v_attrs = &v.attrs;
let v_ident = &v.ident;

all_flags.push(quote::quote!(Self::#v_ident));

let expr = if let Some((_, expr)) = v.discriminant.as_ref() {
quote::quote!(#expr)
} else {
Expand All @@ -36,6 +46,9 @@ pub fn parse(attr: TokenStream, mut item: ItemEnum) -> Result<TokenStream> {

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));

quote::quote!(
#(#v_attrs)*
#vis const #i_ident: #ident = Self { bits: (#expr) ^ !0 };
Expand Down Expand Up @@ -69,12 +82,18 @@ pub fn parse(attr: TokenStream, mut item: ItemEnum) -> Result<TokenStream> {
}

/// Returns a bitmask that contains all values.
///
/// This will include bits that do not have any flags.
/// Use `::full()` if you only want to use flags.
#[inline]
#vis const fn all() -> Self {
Self { bits: !0 }
}

/// Returns `true` if the bitmask contains all values.
///
/// This will check for `bits == !0`,
/// use `.is_full()` if you only want to check for all flags
#[inline]
#vis const fn is_all(&self) -> bool {
self.bits == !0
Expand All @@ -92,6 +111,27 @@ pub fn parse(attr: TokenStream, mut item: ItemEnum) -> Result<TokenStream> {
self.bits == 0
}

/// Returns a bitmask that contains all flags.
#[inline]
#vis const fn full() -> Self {
Self { bits: #(#all_flags.bits |)* 0 }
}

/// Returns `true` if the bitmask contains all flags.
///
/// This will fail if any unused bit is set,
/// consider using `.truncate()` first.
#[inline]
#vis const fn is_full(&self) -> bool {
self.bits == Self::full().bits
}

/// Returns a bitmask that only has bits corresponding to flags
#[inline]
#vis const fn truncate(&self) -> Self {
Self { bits: self.bits & Self::full().bits }
}

/// Returns `true` if `self` intersects with any value in `other`,
/// or if `other` does not contain any values.
///
Expand Down

0 comments on commit 9b19fdf

Please sign in to comment.