#env-var #typenum #meta-programming #proc-macro #math-expressions #unsigned-integer #type-level-integers

typenum-consts

过程宏,它接受一个字面整数值(或简单数学表达式或环境变量的评估结果,其值为字面整数值)并将其转换为 typenum::Unsigned / typenum::Integer 类型的正/负/无符号整数。

6 个版本

0.1.5 2024 年 4 月 17 日
0.1.4 2024 年 4 月 3 日
0.1.2 2024 年 3 月 31 日

879Rust 模式

每月 26 次下载

MIT/Apache

50KB
686

typenum-consts

GitHub Workflow Status Crates.io Version docs.rs

过程宏,它接受一个字面整数值(或简单数学表达式或环境变量的评估结果,其值为字面整数值)并将其转换为 typenum::Unsigned / typenum::Integer 类型的正/负/无符号整数。

有四个宏。

tnconst![...] 可以提供类型级别的正、无符号或负整数。

nconst![...] 提供类型级别的负整数(例如,type A = nconst![69] // A is typenum::consts::N69)。

pconst![...] 提供类型级别的正整数(例如,type A = pconst![69] // A is typenum::consts::P69)。

uconst[...] 提供一个类型级别的无符号整数(例如 type A = uconst![69] // A is typenum::consts::U69)..

为什么?

它节省时间。

假设你想要一个类型级别的正整数 84938493tnconst![+84938493] 会直接输出 typenum::PInt<U84938493>(顺便说一句,P84938493typenum::consts 中不存在)。另一种方法是输入 PInt<Sum<Prod<Exp<..., ...>, ...>, ...>, ...>(这明显需要更多时间)。

示例

# use core::marker::PhantomData;
# use typenum_consts::tnconst;
# use typenum::*;
#
# #[cfg(target_pointer_width = "32")]
# type I32OrI64 = i32;
# #[cfg(target_pointer_width = "64")]
# type I32OrI64 = i64;
type ActualPositive84938493Type = tnconst![+84938493];
type ExpectedPositive84938493Type = PInt< // `PInt` implies positive integer at the type level
Sum<
Prod<Exp<U10, U7>, U8>, // 10**7 * 8
Sum<
Prod<Exp<U10, U6>, U4>, // 10**6 * 4
Sum<
Prod<Exp<U10, U5>, U9>, // 10**5 * 9
Sum<
Prod<Exp<U10, U4>, U3>, // 10**4 * 3
Sum<
Prod<Exp<U10, U3>, U8>, // 10**3 * 8
Sum<
Prod<Exp<U10, U2>, U4>, // 10**2 * 4
Sum<
Prod<Exp<U10, U1>, U9>, // 10**1 * 9
Sum<
Prod<Exp<U10, U0>, U3>, // 10**0 * 3
U0>>>>>>>>
>;

typenum::assert_type_eq!(ExpectedPositive84938493Type, ActualPositive84938493Type);
assert_eq!(
    <ExpectedPositive84938493Type as typenum::ToInt<I32OrI64>>::INT,
    <ActualPositive84938493Type as typenum::ToInt<I32OrI64>>::INT
);

用于条件编译。

假设在不同的环境中,你需要不同的类型级别的整数,你可以使用配置标志,例如,在 'production' 环境中,你可能希望类型别名 NUMBERtypenum::consts::U69,因此你可能这样做:#[cfg(production)] type NUMBER = U69;。或者,你可以这样做

use typenum::{U69, assert_type_eq};
use typenum_consts::uconst;
// ``` .env
// ENV_VAR=69
// ```
type E = uconst![env!("ENV_VAR");];
assert_type_eq!(E, U69);

这是当你直接从环境变量中读取一个整数字符串并使用它作为 typenum 的类型级别整数时的情况。所有的四个宏,即 tnconst![...]pconst![...]uconst![...]nconst![...] 都可以从环境变量中读取整数字符串。

三种使用方法

pconst![...] 为例(其余的宏几乎以相同的方式工作)。

1. 使用一个整数字面量调用它

use typenum::{P123, assert_type_eq};
use typenum_consts::pconst;
type A = pconst![123];
assert_type_eq!(A, P123);

2. 使用表达式或多个简单的数学表达式调用它

use typenum::{P15, assert_type_eq};
use typenum_consts::pconst;
type D = pconst![{
    a = 10;
    b = 5;
    a + b; // Last statement is always the final returned value to be casted into `typenum` type-level integer, e.g. in this example a + b => 10 + 5 => 15, hence it is casted into `P15`
}];
assert_type_eq!(D, P15);

3. 通过读取环境变量来调用它

宏调用 env!(...) 类似于宏,用于在以下四个宏的上下文中特定读取环境变量,即 tnconst!pconst!nconst!uconst!。调用时的第一个参数是必需的,它是将要读取的环境变量的键。第二个参数是可选的,用于指定读取环境变量的 .env.* 文件的路径。例如,env!("ENV_VAR", "./.env.prod")"./.env.prod" 读取 "ENV_VAR" 的值,相对于 CARGO_MANIFEST_DIR

use typenum::{P69, assert_type_eq};
use typenum_consts::pconst;
// ``` .env
// ENV_VAR=69
// ```
type E = pconst![env!("ENV_VAR");];
assert_type_eq!(E, P69);

路线图

  • 数学表达式功能门评估和从环境变量读取。
  • 启用对 Rust 1.70 版本的测试。

许可

根据您的选择,许可如下:

贡献

除非您明确声明,否则任何有意提交以包含在您的工作中的贡献(根据 Apache-2.0 许可证定义),都应按上述方式双重许可,不附加任何其他条款或条件。

依赖关系

~0.5–1MB
~24K SLoC