Rust枚举与布尔类型增强库boolenum的使用,提供高效灵活的布尔与枚举类型转换及操作方法

Rust枚举与布尔类型增强库boolenum的使用

BoolEnum是一个派生宏,用于创建更符合人体工程学的布尔枚举类型,同时减少样板代码。它会为你的枚举自动生成From<bool>Into<bool>Not的实现。

基本用法

use boolenum::BoolEnum;

// 可以使用Yes和No作为变体名(顺序任意)
#[derive(BoolEnum)]
enum UseColors {
    No,
    Yes,
}

// 或者使用True和False
#[derive(BoolEnum)]
enum ShowExpired {
    True,
    False,
}

fn print_things(use_colors: UseColors, show_expired: ShowExpired) {
    if use_colors.into() { // Into<bool>转换
      // ...
    }
}

fn main() {
    print_things(UseColors::Yes, ShowExpired::False)
}

与structopt配合使用

布尔枚举对于区分函数中的布尔参数特别有用,例如你可以写encode(&bytes, Encrypt::Yes, Compress::No)而不是encode(&bytes, true, false)

use boolenum::BoolEnum;
use structopt::StructOpt;

#[derive(BoolEnum)]
enum Verbose { No, Yes }
#[derive(BoolEnum)]
enum Colors { No, Yes }

#[derive(StructOpt)]
struct Opt {
    #[structopt(short, long, parse(from_flag))]
    verbose: Verbose, // 由于Verbose实现了From<bool>,所以可以这样用
    #[structopt(short, long, parse(from_flag))]
    colors: Colors,
}

fn main() {
    let opt = Opt::from_args();
    do_thing(opt.verbose, opt.colors);
}

fn do_thing(verbose: Verbose, colors: Colors) {
    if verbose.into() { }
    if colors.into() { }
}

完整示例

以下是一个完整的示例,展示如何使用boolenum库:

use boolenum::BoolEnum;

// 定义一个使用颜色的枚举
#[derive(BoolEnum, Debug)]
enum UseColors {
    Yes,
    No,
}

// 定义一个显示过期项的枚举
#[derive(BoolEnum, Debug)]
enum ShowExpired {
    True,
    False,
}

fn main() {
    // 从布尔值创建枚举实例
    let use_colors = UseColors::from(true);
    let show_expired = ShowExpired::from(false);
    
    println!("Use colors: {:?}", use_colors); // 输出: Use colors: Yes
    println!("Show expired: {:?}", show_expired); // 输出: Show expired: False
    
    // 将枚举转换为布尔值
    let should_use_colors: bool = use_colors.into();
    let should_show_expired: bool = show_expired.into();
    
    println!("Should use colors: {}", should_use_colors); // 输出: Should use colors: true
    println!("Should show expired: {}", should_show_expired); // 输出: Should show expired: false
    
    // 使用模式匹配
    match use_colors {
        UseColors::Yes => println!("Using colors"),
        UseColors::No => println!("Not using colors"),
    }
    
    // 使用Not操作
    let inverted = !use_colors;
    println!("Inverted: {:?}", inverted); // 输出: Inverted: No
}

注意事项

BoolEnum适用于具有两个单元变体的枚举,这些变体可以命名为Yes和No,或者True和False。变体在枚举中的顺序不重要。

该库在MIT或Apache-2.0许可证下发布。

完整示例demo

以下是一个更完整的示例,展示boolenum在实际项目中的应用:

use boolenum::BoolEnum;

// 定义应用配置选项
#[derive(BoolEnum, Debug, PartialEq)]
enum Logging {
    Enabled,
    Disabled,
}

#[derive(BoolEnum, Debug, PartialEq)]
enum Cache {
    On,
    Off,
}

#[derive(Debug)]
struct AppConfig {
    logging: Logging,
    cache: Cache,
}

impl AppConfig {
    fn new(logging: Logging, cache: Cache) -> Self {
        Self { logging, cache }
    }
    
    fn print_config(&self) {
        println!("Application Configuration:");
        println!("Logging: {:?}", self.logging);
        println!("Cache: {:?}", self.cache);
    }
}

fn main() {
    // 从布尔值创建配置
    let config = AppConfig::new(
        Logging::from(true),  // 启用日志
        Cache::from(false)    // 禁用缓存
    );
    
    config.print_config();
    
    // 检查配置项
    if config.logging.into() {
        println!("Logging is enabled");
    }
    
    if !config.cache.into() {
        println!("Cache is disabled");
    }
    
    // 使用模式匹配处理配置
    match config.cache {
        Cache::On => println!("Cache is on"),
        Cache::Off => println!("Cache is off"),
    }
    
    // 使用Not操作符
    let inverted_logging = !config.logging;
    println!("Inverted logging: {:?}", inverted_logging);
}

这个示例展示了如何:

  1. 定义多个布尔枚举类型
  2. 在结构体中使用这些枚举
  3. 进行布尔值转换和逻辑操作
  4. 使用模式匹配处理枚举值
  5. 使用Not操作符进行取反操作

1 回复

Rust枚举与布尔类型增强库boolenum的使用指南

boolenum是一个Rust库,提供了高效灵活的布尔与枚举类型之间的转换及操作方法。它简化了在Rust中使用枚举作为布尔值替代品的场景,特别是在需要更明确语义的情况下。

主要特性

  1. 在布尔值和枚举值之间进行双向转换
  2. 提供类似布尔操作的枚举方法
  3. 零成本抽象,保证高性能
  4. 支持自定义枚举类型

安装

Cargo.toml中添加依赖:

[dependencies]
boolenum = "0.2"

基本用法

1. 使用预定义的BoolEnum

use boolenum::BoolEnum;

#[derive(Debug, PartialEq)]
enum Status {
    Active,
    // 对应true
    Inactive,  // 对应false
}

impl BoolEnum for Status {
    fn into_bool(self) -> bool {
        match self {
            Status::Active => true,
            Status::Inactive => false,
        }
    }

    fn from_bool(value: bool) -> Self {
        if value {
            Status::Active
        } else {
            Status::Inactive
        }
    }
}

fn main() {
    let active = Status::Active;
    assert_eq!(active.into_bool(), true);
    
    let from_true = Status::from_bool(true);
    assert_eq!(from_true, Status::Active);
}

2. 使用boolenum宏简化实现

use boolenum::boolenum;

#[boolenum]
#[derive(Debug, PartialEq)]
enum NetworkState {
    Connected,  // true
    Disconnected, // false
}

fn main() {
    let state = NetworkState::Connected;
    assert!(state.to_bool());
    
    let new_state = NetworkState::from_bool(false);
    assert_eq!(new_state, NetworkState::Disconnected);
}

3. 枚举布尔操作

use boolenum::{BoolEnum, BoolEnumOps};

#[derive(BoolEnum, BoolEnumOps)]
#[boolenum]
enum Switch {
    On,
    Off,
}

fn main() {
    let switch = Switch::On;
    
    // 取反操作
    let inverted = switch.not();
    assert_eq!(inverted, Switch::Off);
    
    // 与操作
    let and_result = switch.and(Switch::Off);
    assert_eq!(and_result, Switch::Off);
    
    // 或操作
    let or_result = switch.or(Switch::Off);
    assert_eq!(or_result, Switch::On);
}

4. 自定义转换规则

use boolenum::BoolEnum;

#[derive(Debug, PartialEq)]
enum Access {
    Granted,
    Denied,
}

impl BoolEnum for Access {
    fn into_bool(self) -> bool {
        match self {
            Access::Granted => true,
            Access::Denied => false,
        }
    }

    fn from_bool(value: bool) -> Self {
        if value {
            Access::Granted
        } else {
            Access::Denied
        }
    }
}

fn main() {
    let access = Access::Granted;
    if access.to_bool() {
        println!("Access granted!");
    }
}

高级用法

条件执行

use boolenum::{BoolEnum, BoolEnumOps};

#[derive(BoolEnum, BoolEnumOps)]
#[boolenum]
enum TaskStatus {
    Complete,
    Incomplete,
}

fn main() {
    let status = TaskStatus::Incomplete;
    
    // 只有当状态为Complete时才执行
    status.if_true(|| {
        println!("Task is complete!");
    });
    
    // 只有当状态为Incomplete时才执行
    status.if_false(|| {
        println!("Task is still incomplete.");
    });
}

模式匹配增强

use boolenum::BoolEnum;

#[derive(BoolEnum)]
#[boolenum]
enum Light {
    On,
    Off,
}

fn main() {
    let light = Light::On;
    
    match light {
        Light::On => println!("Light is on"),
        Light::Off => println!("Light is off"),
    }
    
    // 可以直接在if条件中使用
    if light.to_bool() {
        println!("It's bright!");
    }
}

性能考虑

boolenum设计为零成本抽象,所有转换和操作在编译时都会被优化为直接的布尔操作,不会引入运行时开销。

适用场景

  1. 需要更明确语义的布尔值(如Enabled/Disabledtrue/false更清晰)
  2. 需要为布尔状态添加额外数据或行为
  3. 需要在不同布尔表示之间进行转换
  4. 需要扩展布尔逻辑到自定义类型

完整示例

以下是一个结合了boolenum多种功能的完整示例:

use boolenum::{boolenum, BoolEnum, BoolEnumOps};

// 使用宏简化实现
#[boolenum]
#[derive(Debug, PartialEq, BoolEnumOps)]
enum UserRole {
    Admin,   // 对应true
    Guest,   // 对应false
}

// 自定义实现
#[derive(Debug, PartialEq)]
enum Subscription {
    Premium,
    Free,
}

impl BoolEnum for Subscription {
    fn into_bool(self) -> bool {
        match self {
            Subscription::Premium => true,
            Subscription::Free => false,
        }
    }

    fn from_bool(value: bool) -> Self {
        if value { Subscription::Premium } else { Subscription::Free }
    }
}

fn main() {
    // 基本转换
    let role = UserRole::Admin;
    assert!(role.to_bool());
    assert_eq!(UserRole::from_bool(true), UserRole::Admin);
    
    // 布尔操作
    let inverted = role.not();
    assert_eq!(inverted, UserRole::Guest);
    
    let and_result = role.and(UserRole::Guest);
    assert_eq!(and_result, UserRole::Guest);
    
    // 条件执行
    role.if_true(|| {
        println!("User is an admin"); // 会执行
    });
    
    // 自定义类型使用
    let sub = Subscription::Premium;
    if sub.to_bool() {
        println!("User has premium subscription"); // 会执行
    }
    
    // 模式匹配
    match sub {
        Subscription::Premium => println!("Premium features unlocked"),
        Subscription::Free => println!("Basic features only"),
    }
}

这个示例展示了:

  1. 使用boolenum宏简化实现
  2. 手动实现BoolEnum trait
  3. 使用布尔操作(not, and等)
  4. 条件执行功能
  5. 模式匹配增强
  6. 自定义类型的使用

boolenum为Rust开发者提供了一种类型安全、语义明确的方式来处理布尔逻辑,同时保持了原生布尔值的性能和简洁性。

回到顶部