What is the purpose of bitflags::Flags::contains_all for comprehensive flag checking?

contains_all checks whether a flags value has all specified bits set, returning true only if every flag in the argument is also present in the value being checked. This is the strictest membership check in bitflags, requiring complete containment rather than partial overlap, and is essential for validating that a value satisfies all requirements from a set of flags.

Basic contains_all Usage

use bitflags::bitflags;
 
bitflags! {
    #[derive(Clone, Copy, Debug)]
    struct Permissions: u32 {
        const READ = 0b0001;
        const WRITE = 0b0010;
        const EXECUTE = 0b0100;
        const ADMIN = 0b1000;
    }
}
 
fn basic_usage() {
    let read_write = Permissions::READ | Permissions::WRITE;
    let all_perms = Permissions::READ | Permissions::WRITE | Permissions::EXECUTE | Permissions::ADMIN;
    
    // contains_all: Does the value have ALL specified flags?
    assert!(read_write.contains_all(Permissions::READ));
    assert!(read_write.contains_all(Permissions::WRITE));
    assert!(read_write.contains_all(Permissions::READ | Permissions::WRITE));
    
    // Does NOT contain all - missing EXECUTE
    assert!(!read_write.contains_all(Permissions::READ | Permissions::EXECUTE));
    
    // Does NOT contain all - missing ADMIN
    assert!(!read_write.contains_all(Permissions::all()));
    
    // All permissions contains everything
    assert!(all_perms.contains_all(Permissions::all()));
}

contains_all requires every specified bit to be set in the value.

contains_all vs contains

use bitflags::bitflags;
 
bitflags! {
    #[derive(Clone, Copy)]
    struct Flags: u8 {
        const A = 0b0001;
        const B = 0b0010;
        const C = 0b0100;
        const D = 0b1000;
    }
}
 
fn contains_vs_contains_all() {
    let value = Flags::A | Flags::B | Flags::C;  // 0b0111
    
    // contains: Does value have this ONE flag?
    assert!(value.contains(Flags::A));      // Yes, A is set
    assert!(value.contains(Flags::B));      // Yes, B is set
    assert!(!value.contains(Flags::D));     // No, D is not set
    
    // contains_all: Does value have ALL specified flags?
    assert!(value.contains_all(Flags::A));              // Single flag, same as contains
    assert!(value.contains_all(Flags::A | Flags::B));   // Both A and B are set
    assert!(value.contains_all(Flags::A | Flags::B | Flags::C)); // All three are set
    assert!(!value.contains_all(Flags::A | Flags::D)); // D is not set
    
    // Key difference: contains checks one flag, contains_all checks multiple
    // contains(Flags::A | Flags::B) is NOT valid - takes only one flag
    // contains_all(Flags::A | Flags::B) is valid - checks all flags
}

contains is for single flags; contains_all is for multiple flags.

contains_all vs intersects

use bitflags::bitflags;
 
bitflags! {
    #[derive(Clone, Copy)]
    struct Status: u8 {
        const ACTIVE = 0b0001;
        const PENDING = 0b0010;
        const VERIFIED = 0b0100;
        const SUSPENDED = 0b1000;
    }
}
 
fn contains_all_vs_intersects() {
    let status = Status::ACTIVE | Status::VERIFIED;  // 0b0101
    
    // intersects: Is there ANY overlap? (partial)
    assert!(status.intersects(Status::ACTIVE | Status::PENDING));   
    // ACTIVE is set, so intersects returns true even though PENDING is not
    
    assert!(status.intersects(Status::VERIFIED | Status::SUSPENDED)); 
    // VERIFIED is set, so intersects returns true
    
    // contains_all: Are ALL flags set? (complete)
    assert!(status.contains_all(Status::ACTIVE | Status::VERIFIED));  
    // Both ACTIVE and VERIFIED are set
    
    assert!(!status.contains_all(Status::ACTIVE | Status::PENDING));   
    // ACTIVE is set but PENDING is not
    
    assert!(!status.contains_all(Status::VERIFIED | Status::SUSPENDED)); 
    // VERIFIED is set but SUSPENDED is not
    
    // Summary:
    // intersects: "Is ANY of these flags set?" (OR logic)
    // contains_all: "Are ALL of these flags set?" (AND logic)
}

intersects checks for any overlap; contains_all checks for complete containment.

Permission Checking Pattern

use bitflags::bitflags;
 
bitflags! {
    #[derive(Clone, Copy)]
    struct FilePermissions: u32 {
        const READ = 0b0001;
        const WRITE = 0b0010;
        const EXECUTE = 0b0100;
        const ADMIN = 0b1000;
    }
}
 
struct File {
    name: String,
    permissions: FilePermissions,
}
 
fn check_access(file: &File, required: FilePermissions) -> bool {
    // Check if user has ALL required permissions
    file.permissions.contains_all(required)
}
 
fn permission_example() {
    let readable_file = File {
        name: "data.txt".to_string(),
        permissions: FilePermissions::READ,
    };
    
    let writable_file = File {
        name: "output.txt".to_string(),
        permissions: FilePermissions::READ | FilePermissions::WRITE,
    };
    
    // Check single permission
    assert!(check_access(&readable_file, FilePermissions::READ));
    assert!(!check_access(&readable_file, FilePermissions::WRITE));
    
    // Check multiple permissions
    let read_write = FilePermissions::READ | FilePermissions::WRITE;
    assert!(!check_access(&readable_file, read_write));  // Missing WRITE
    assert!(check_access(&writable_file, read_write));   // Has both
    
    // Admin can do anything (if checking ADMIN specifically)
    let admin_file = File {
        name: "system.cfg".to_string(),
        permissions: FilePermissions::ADMIN,
    };
    // Note: ADMIN doesn't automatically imply other permissions
    // Application logic must decide how ADMIN interacts with other checks
}

Use contains_all to verify that all required permissions are present.

Capability Requirements Pattern

use bitflags::bitflags;
 
bitflags! {
    #[derive(Clone, Copy)]
    struct Capabilities: u32 {
        const CAN_READ = 0b0001;
        const CAN_WRITE = 0b0010;
        const CAN_DELETE = 0b0100;
        const CAN_SHARE = 0b1000;
    }
}
 
struct User {
    name: String,
    capabilities: Capabilities,
}
 
fn perform_operation(user: &User, operation: &str) -> Result<(), &'static str> {
    let required = match operation {
        "read" => Capabilities::CAN_READ,
        "write" => Capabilities::CAN_WRITE | Capabilities::CAN_READ,
        "delete" => Capabilities::CAN_DELETE | Capabilities::CAN_READ,
        "share" => Capabilities::CAN_SHARE | Capabilities::CAN_READ,
        _ => return Err("Unknown operation"),
    };
    
    if user.capabilities.contains_all(required) {
        Ok(())
    } else {
        Err("Insufficient capabilities")
    }
}
 
fn capability_example() {
    let reader = User {
        name: "reader".to_string(),
        capabilities: Capabilities::CAN_READ,
    };
    
    let writer = User {
        name: "writer".to_string(),
        capabilities: Capabilities::CAN_READ | Capabilities::CAN_WRITE,
    };
    
    let admin = User {
        name: "admin".to_string(),
        capabilities: Capabilities::all(),
    };
    
    // Read requires only CAN_READ
    assert!(perform_operation(&reader, "read").is_ok());
    
    // Write requires CAN_READ and CAN_WRITE
    assert!(perform_operation(&reader, "write").is_err());  // Missing CAN_WRITE
    assert!(perform_operation(&writer, "write").is_ok());   // Has both
    
    // Delete requires CAN_DELETE and CAN_READ
    assert!(perform_operation(&writer, "delete").is_err()); // Missing CAN_DELETE
    assert!(perform_operation(&admin, "delete").is_ok());   // Has all
    
    // Admin has everything
    assert!(perform_operation(&admin, "share").is_ok());
}

Combine multiple capabilities with | and check with contains_all.

Feature Flag Pattern

use bitflags::bitflags;
 
bitflags! {
    #[derive(Clone, Copy)]
    struct Features: u32 {
        const FEATURE_A = 0b0001;
        const FEATURE_B = 0b0010;
        const FEATURE_C = 0b0100;
        const PREMIUM = 0b1000;
    }
}
 
struct Config {
    features: Features,
}
 
fn is_feature_enabled(config: &Config, feature: Features) -> bool {
    config.features.contains_all(feature)
}
 
fn require_features(config: &Config, features: Features) -> Result<(), String> {
    let missing = features & !config.features;
    if missing.is_empty() {
        Ok(())
    } else {
        Err(format!("Missing features: {:?}", missing))
    }
}
 
fn feature_example() {
    let basic_config = Config {
        features: Features::FEATURE_A | Features::FEATURE_B,
    };
    
    let premium_config = Config {
        features: Features::all(),
    };
    
    // Check single feature
    assert!(is_feature_enabled(&basic_config, Features::FEATURE_A));
    assert!(!is_feature_enabled(&basic_config, Features::FEATURE_C));
    
    // Check multiple features
    assert!(is_feature_enabled(&basic_config, Features::FEATURE_A | Features::FEATURE_B));
    assert!(!is_feature_enabled(&basic_config, Features::FEATURE_A | Features::FEATURE_C));
    
    // Require multiple features
    assert!(require_features(&basic_config, Features::FEATURE_A | Features::FEATURE_B).is_ok());
    assert!(require_features(&basic_config, Features::FEATURE_A | Features::FEATURE_C).is_err());
    
    // Premium has all features
    assert!(require_features(&premium_config, Features::all()).is_ok());
}

Use contains_all to check if all required features are enabled.

Empty Set Behavior

use bitflags::bitflags;
 
bitflags! {
    #[derive(Clone, Copy)]
    struct Flags: u8 {
        const A = 0b0001;
        const B = 0b0010;
    }
}
 
fn empty_set_behavior() {
    let value = Flags::A | Flags::B;
    
    // contains_all with empty set always returns true
    // (All zero flags are set in any value)
    assert!(value.contains_all(Flags::empty()));
    
    // This is mathematically consistent:
    // "Does value contain all flags in empty set?"
    // Yes, vacuously true - there are no flags to check
    
    let empty_value = Flags::empty();
    
    // Even empty value contains all flags from empty set
    assert!(empty_value.contains_all(Flags::empty()));
    
    // But empty value does NOT contain any actual flags
    assert!(!empty_value.contains_all(Flags::A));
    assert!(!empty_value.contains_all(Flags::B));
    assert!(!empty_value.contains_all(Flags::A | Flags::B));
}

contains_all(Flags::empty()) is always true—empty sets are trivially contained.

All Flags Behavior

use bitflags::bitflags;
 
bitflags! {
    #[derive(Clone, Copy)]
    struct Flags: u8 {
        const A = 0b0001;
        const B = 0b0010;
        const C = 0b0100;
    }
}
 
fn all_flags_behavior() {
    // contains_all(Flags::all()) checks if all defined flags are set
    let partial = Flags::A | Flags::B;
    let complete = Flags::A | Flags::B | Flags::C;  // Same as Flags::all()
    
    // partial doesn't contain all flags
    assert!(!partial.contains_all(Flags::all()));
    assert!(!partial.contains_all(Flags::A | Flags::B | Flags::C));  // Same check
    
    // complete contains all flags
    assert!(complete.contains_all(Flags::all()));
    assert!(complete.contains_all(Flags::A | Flags::B | Flags::C));
    
    // This is useful for validation: "Is every flag set?"
    fn is_complete(flags: Flags) -> bool {
        flags.contains_all(Flags::all())
    }
    
    assert!(!is_complete(partial));
    assert!(is_complete(complete));
}

contains_all(Flags::all()) checks if every defined flag is present.

Combining with Other Operations

use bitflags::bitflags;
 
bitflags! {
    #[derive(Clone, Copy)]
    struct Flags: u32 {
        const A = 0b0001;
        const B = 0b0010;
        const C = 0b0100;
        const D = 0b1000;
    }
}
 
fn combined_operations() {
    let value = Flags::A | Flags::B | Flags::C;
    
    // Check with union
    let check = Flags::A | Flags::B;
    assert!(value.contains_all(check));
    
    // Check with intersection
    let intersection = value & Flags::A;
    assert!(intersection.contains_all(Flags::A));
    assert!(!intersection.contains_all(Flags::A | Flags::B));
    
    // Check with difference
    let difference = value - Flags::A;  // B | C
    assert!(difference.contains_all(Flags::B | Flags::C));
    assert!(!difference.contains_all(Flags::A));
    
    // Toggle and check
    let toggled = value ^ Flags::D;  // A | B | C | D
    assert!(toggled.contains_all(Flags::A | Flags::B | Flags::C | Flags::D));
    
    // Check complement
    let complement = !Flags::A;
    // complement has B, C, D set (and possibly more bits)
    assert!(complement.contains_all(Flags::B | Flags::C | Flags::D));
}

contains_all works naturally with bitwise operations.

Finding Missing Flags

use bitflags::bitflags;
 
bitflags! {
    #[derive(Clone, Copy, Debug)]
    struct Permissions: u32 {
        const READ = 0b0001;
        const WRITE = 0b0010;
        const EXECUTE = 0b0100;
    }
}
 
fn find_missing() {
    let required = Permissions::READ | Permissions::WRITE | Permissions::EXECUTE;
    let available = Permissions::READ | Permissions::WRITE;
    
    if !available.contains_all(required) {
        // Find which flags are missing
        let missing = required & !available;
        println!("Missing permissions: {:?}", missing);
        // Missing permissions: EXECUTE
    }
    
    // This pattern is useful for reporting errors
    fn explain_missing(available: Permissions, required: Permissions) -> Option<String> {
        if available.contains_all(required) {
            return None;
        }
        
        let missing = required & !available;
        Some(format!("Missing permissions: {:?}", missing))
    }
    
    assert_eq!(
        explain_missing(available, required),
        Some("Missing permissions: Permissions(0b100)".to_string())
    );
    
    assert_eq!(
        explain_missing(Permissions::all(), required),
        None
    );
}

Use required & !available to find which flags are missing.

Validation and Error Messages

use bitflags::bitflags;
 
bitflags! {
    #[derive(Clone, Copy, Debug)]
    struct Config: u32 {
        const ENABLED = 0b0001;
        const VERBOSE = 0b0010;
        const DEBUG = 0b0100;
        const SECURE = 0b1000;
    }
}
 
#[derive(Debug)]
struct ConfigError {
    missing: Config,
}
 
fn validate_config(config: Config) -> Result<(), ConfigError> {
    // Required configuration
    let required = Config::ENABLED | Config::SECURE;
    
    if config.contains_all(required) {
        Ok(())
    } else {
        Err(ConfigError {
            missing: required & !config,
        })
    }
}
 
fn validation_example() {
    let valid_config = Config::ENABLED | Config::SECURE | Config::VERBOSE;
    let invalid_config = Config::ENABLED | Config::VERBOSE;
    
    assert!(validate_config(valid_config).is_ok());
    
    match validate_config(invalid_config) {
        Ok(()) => unreachable!(),
        Err(e) => {
            println!("Configuration error: missing {:?}", e.missing);
            // Configuration error: missing SECURE
        }
    }
}

Provide detailed error messages showing which flags are missing.

Performance Characteristics

use bitflags::bitflags;
 
bitflags! {
    #[derive(Clone, Copy)]
    struct Flags: u64 {
        const A = 0b0001;
        const B = 0b0010;
        // ... potentially 64 different flags
    }
}
 
fn performance() {
    let value = Flags::A | Flags::B;
    let check = Flags::A;
    
    // contains_all is O(1) - single bitwise operation
    // (value.bits & check.bits) == check.bits
    // One AND operation and one comparison
    
    // This is extremely fast regardless of number of flags
    for _ in 0..1_000_000 {
        let _ = value.contains_all(check);
    }
    
    // Compare to loop-based checking (O(n) where n is number of flags):
    // Slower because it needs to iterate and check each flag
}

contains_all is a constant-time bitwise operation.

Type Safety with bitflags

use bitflags::bitflags;
 
bitflags! {
    #[derive(Clone, Copy)]
    struct Status: u32 {
        const RUNNING = 0b0001;
        const PAUSED = 0b0010;
        const STOPPED = 0b0100;
        const ERROR = 0b1000;
    }
}
 
bitflags! {
    #[derive(Clone, Copy)]
    struct Permissions: u32 {
        const READ = 0b0001;
        const WRITE = 0b0010;
    }
}
 
fn type_safety() {
    let status = Status::RUNNING | Status::PAUSED;
    let perms = Permissions::READ | Permissions::WRITE;
    
    // Compile error: mismatched types
    // status.contains_all(perms);  // Won't compile
    
    // Each bitflags type is separate
    // Can't mix Status and Permissions
    
    // This prevents accidentally checking wrong flags
}

bitflags generates distinct types, preventing accidental mixing of different flag types.

Synthesis

Quick reference:

Method Question Answered Returns True If
contains(Flag) Is this one flag set? That specific bit is 1
contains_all(Flags) Are ALL these flags set? All specified bits are 1
intersects(Flags) Is ANY of these flags set? Any specified bit is 1
is_empty() Is no flag set? All bits are 0

Common patterns:

use bitflags::bitflags;
 
bitflags! {
    #[derive(Clone, Copy)]
    struct Flags: u32 {
        const A = 0b0001;
        const B = 0b0010;
        const C = 0b0100;
    }
}
 
fn patterns() {
    let value = Flags::A | Flags::B;
    
    // Single flag check
    if value.contains(Flags::A) {
        // A is set
    }
    
    // Multiple flags check (all required)
    if value.contains_all(Flags::A | Flags::B) {
        // Both A and B are set
    }
    
    // Multiple flags check (any allowed)
    if value.intersects(Flags::A | Flags::C) {
        // Either A or C is set (A is)
    }
    
    // Validate complete set
    if value.contains_all(Flags::all()) {
        // Every defined flag is set
    }
    
    // Find missing flags
    let required = Flags::A | Flags::B | Flags::C;
    if !value.contains_all(required) {
        let missing = required & !value;
        // missing contains C
    }
}

Key insight: contains_all implements the subset operation for flags—it asks "is the argument a subset of the value?" by checking whether all bits set in the argument are also set in the value. This is the strictest containment check, requiring complete overlap rather than any intersection. The implementation is a single bitwise AND followed by an equality comparison: (value.bits & check.bits) == check.bits. This constant-time operation makes it efficient for permission checks, capability validation, and feature flag verification. Use contains_all when you need to ensure that a value satisfies all requirements from a set of flags, as opposed to intersects which checks for any overlap or contains which checks a single flag. The method is particularly useful for validating user capabilities before operations, checking that all required features are enabled, or ensuring that configuration flags are complete.