#boolean #type #condition #depend #const

no-std dev condtype

通过布尔常量在编译时选择类型

4 个稳定版本

1.3.0 2023年8月20日
1.2.0 2023年5月9日
1.1.0 2023年4月25日
1.0.0 2023年4月18日

#345Rust 模式

Download history 5729/week @ 2024-04-14 6167/week @ 2024-04-21 6297/week @ 2024-04-28 4324/week @ 2024-05-05 5328/week @ 2024-05-12 5709/week @ 2024-05-19 5762/week @ 2024-05-26 6356/week @ 2024-06-02 6415/week @ 2024-06-09 6100/week @ 2024-06-16 4540/week @ 2024-06-23 4857/week @ 2024-06-30 6034/week @ 2024-07-07 7514/week @ 2024-07-14 7086/week @ 2024-07-21 6746/week @ 2024-07-28

28,005 每月下载量
74 个 crate 中使用 (通过 divan)

MIT/Apache

22KB
161

condtype

docs.rs crates.io github

通过布尔常量在编译时选择 Rust 类型,由 Nikolai Vazquez 提供。

如果你觉得这个库很有用,可以考虑 star 它,以及 赞助一次性捐赠 💖

条件类型

CondType 类型和 condval! 宏通过布尔常量在编译时选择类型,就像 C++ 中的 std::conditional_t 一样。与 Either 类型不同,CondType/condval! 选择的是直接使用,而不是用 enum 类型包裹。这可以被认为是一种 依赖类型 的形式,但它的能力有限,并且仅限于编译时常量,而不是运行时值。

CondType

在下面的例子中,CondType 根据布尔 泛型常量 的值,别名 &stri32

use condtype::CondType;

let str: CondType<true,  &str, i32> = "hello";
let int: CondType<false, &str, i32> = 42;

// Unsized types are also supported:
let str: &CondType<true, str, [u8]> = "world";

condval!

condval! 允许在不指定类型的情况下选择不同类型的值。在以下示例中,val 被推断为是 &stri32,具体取决于 COND

use condtype::condval;

const COND: bool = true;

let val = condval!(if COND {
    "hello"
} else {
    42
});

assert_eq!(val, "hello");

if let 模式匹配也受到支持

use condtype::condval;

const STR: Option<&str> = Some("hello");

let val = condval!(if let Some(str) = STR {
    str.to_uppercase()
} else {
    42
});

assert_eq!(val, "HELLO");

特定平台类型

该库可以通过使用特定平台常数的更小尺寸类型来提高某些平台上代码的效率。

在以下示例中,RlimOption 类型可以是 Option<rlim_t>rlim_t 本身,其中如果 rlim_t::MAX 不等于 RLIM_INFINITY,它可以被当作 Option::None 的哨兵值。

use condtype::{condval, CondType};
use libc::{rlim_t, RLIM_INFINITY};

const RLIM_INFINITY_IS_MAX: bool = RLIM_INFINITY == rlim_t::MAX;

type RlimOption = CondType<RLIM_INFINITY_IS_MAX, Option<rlim_t>, rlim_t>;

const RLIM_NONE: RlimOption = condval!(if RLIM_INFINITY_IS_MAX {
    None::<rlim_t>
} else {
    rlim_t::MAX
});

// Convert from either `RlimOption` type to `Option` via the `Into` trait:
let rlim_none: Option<rlim_t> = RLIM_NONE.into();

如果没有这个库,可以通过使用 cfg_if! 来达到相同的目标。然而,使用 #[cfg] 需要维护一个平台列表,并且在 RLIM_INFINITY 依赖于 CPU 架构时需要更加细致。

use cfg_if::cfg_if;
use libc::rlim_t;

cfg_if! {
    // Platforms where `RLIM_INFINITY != rlim_t::MAX`:
    if #[cfg(any(
        target_os = "macos",
        target_os = "freebsd",
        target_os = "solaris",
        // ad nauseam...
    ))] {
        type RlimOption = rlim_t;
        const RLIM_NONE: RlimOption = rlim_t::MAX;
    } else {
        type RlimOption = Option<rlim_t>;
        const RLIM_NONE: RlimOption = None;
    }
}

限制

目前无法使用 CondTypecondval! 与一个 泛型常量,因为 Rust 还没有将基于布尔值的特实现视为详尽的。一旦该问题得到解决,此库的所有版本都应与泛型常量“正常工作”。

fn generic<const B: bool>() {
    let val: CondType<B, &str, i32> = condval!(if B {
        "hello"
    } else {
        42
    });
}

安装

此库在 crates.io 上可用,您可以通过在项目目录中运行以下 cargo 命令来使用它

cargo add condtype

或者通过手动将以下内容添加到您项目的 Cargo.toml

[dependencies]
condtype = "1.3.0"

许可证

像 Rust 项目一样,此库可以在 MIT 许可证Apache 许可证(版本 2.0) 下使用。

无运行时依赖