Skip to main content

impl_flags

Macro impl_flags 

Source
macro_rules! impl_flags {
    (
        $(#[$outer_flags:meta])*
        $vis_flags:vis struct $flags:ident($ty:ty);

        $(#[$outer_flag:meta])*
        $vis_flag:vis enum $flag:ident {
            $(
                $(#[$inner_flag:meta])*
                $name:ident = $value:expr
            ),+ $( , )?
        }
    ) => { ... };
}
Expand description

Common helper for declaring bitflag and bitmask types.

This macro takes as input:

  • A struct declaration representing a bitmask type (e.g., pub struct Permissions(u32)).
  • An enumeration declaration representing individual bit flags (e.g., pub enum Permission { ... }).

And generates:

  • The struct and enum types with appropriate #[repr] attributes.
  • Implementations of common bitflag operators (::core::ops::BitOr, ::core::ops::BitAnd, etc.).
  • Utility methods such as .contains() to check flags.

ยงExamples

use kernel::impl_flags;

impl_flags!(
    /// Represents multiple permissions.
    #[derive(Debug, Clone, Default, Copy, PartialEq, Eq)]
    pub struct Permissions(u32);

    /// Represents a single permission.
    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
    pub enum Permission {
        /// Read permission.
        Read = 1 << 0,

        /// Write permission.
        Write = 1 << 1,

        /// Execute permission.
        Execute = 1 << 2,
    }
);

// Combine multiple permissions using the bitwise OR (`|`) operator.
let mut read_write: Permissions = Permission::Read | Permission::Write;
assert!(read_write.contains(Permission::Read));
assert!(read_write.contains(Permission::Write));
assert!(!read_write.contains(Permission::Execute));
assert!(read_write.contains_any(Permission::Read | Permission::Execute));
assert!(read_write.contains_all(Permission::Read | Permission::Write));

// Using the bitwise OR assignment (`|=`) operator.
read_write |= Permission::Execute;
assert!(read_write.contains(Permission::Execute));

// Masking a permission with the bitwise AND (`&`) operator.
let read_only: Permissions = read_write & Permission::Read;
assert!(read_only.contains(Permission::Read));
assert!(!read_only.contains(Permission::Write));

// Toggling permissions with the bitwise XOR (`^`) operator.
let toggled: Permissions = read_only ^ Permission::Read;
assert!(!toggled.contains(Permission::Read));

// Inverting permissions with the bitwise NOT (`!`) operator.
let negated = !read_only;
assert!(negated.contains(Permission::Write));
assert!(!negated.contains(Permission::Read));