1 个不稳定版本
0.1.0 | 2024 年 3 月 2 日 |
---|
#1127 in Rust 模式
66KB
1K SLoC
ucsi
库
ucsi
库提供基于 SI 的单位类型系统和值的零成本单位包装。
您可以使用这些包的值进行正常算术(因为它们重载了运算符),然后 Rust 的泛型引擎和 ucsi 将帮助您推导它们的类型。
感谢 Rust 强大的类型系统和静态评估器,ucsi 允许您在编译时知道您的算术违反了什么,并且提供了对常量算术的完美支持。
同时,您可以轻松创建自己的类型(请参阅 unit!
宏和 macros
模块),这些类型可以与 ucsi 的类型系统无缝协作。
快速入门
use ucsi::units::base::{kg, m, s};
use ucsi::unit;
use ucsi::Value;
// create your new unit
// see the `unit` macro or `ucsi::core::ops` for more information.
type Newton = unit!((kg * m) / (s ** { 2 }));
// build some value
// `Value<value_type, value_unit>`
let speed: Value<f64, unit!(m / s)> = Value::new(10.0);
let time: Value<f64, s> = Value::new(1.0);
let acc = speed / time;
let mass: Value<f64, kg> = Value::new(1.0);
// this is `newton` in SI,
// but not now because it's currently typed as `((m / s) / s) * kg`
let force = acc * mass;
// lets cast it to newton
let checked_force: Value<_, Newton> =
// note the `cast_const` here. `f64` is copy, so this cast is const-able.
// If your value is not copy-able, use `cast` instead.
force.cast_const();
由于 Rust 的常量评估,类型转换是 编译时检查 的!
为了阐明类型转换检查,考虑以下示例
let s_can_never_be_newton: Value<_, s> = force.cast_const();
上面的示例无法编译,并会抛出一些错误,例如
error[E0080]: evaluation of `<Second as CastFrom<ucsi::ops::Mul<ucsi::ops::Div<ucsi::ops::Div<Meter, Second>, Second>,
Kilogram>>>::CAN_CAST_FROM` failed
--> D:\WBH\rust\ucsi\ucsi\src\core\units\any.rs:25:9
|
25 | panic!("cannot cast si type")
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'cannot cast si type', D:\WBH\rust\ucsi\ucsi\src\core\units\any.rs:25:9
|
note: inside `is_same_type_or_panic::<ucsi::ops::Mul<ucsi::ops::Div<ucsi::ops::Div<Meter, Second>, Second>, Kilogram>,
Second>`
--> D:\WBH\rust\ucsi\ucsi\src\core\units\any.rs:25:9
|
25 | panic!("cannot cast si type")
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: inside `<Second as CastFrom<ucsi::ops::Mul<ucsi::ops::Div<ucsi::ops::Div<Meter, Second>, Second>, Kilogram>>>::CAN_CAST_FROM`
--> D:\WBH\rust\ucsi\ucsi\src\core\units\any.rs:36:9
|
36 | is_same_type_or_panic::<T, B>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
note: the above error was encountered while instantiating `fn ucsi::Value::<f64, ucsi::ops::Mul<ucsi::ops::Div<ucsi::ops::Div<ucsi::units::base::Meter, ucsi::units::base::Second>, ucsi::units::base::Second>, ucsi::units::base::Kilogram>>::cast_const::<ucsi::units::base::Second>`
--> ucsi-test\tests\test_ops.rs:26:25
|
26 | let s_can_never_be_newton: Value<_, s> = force.cast_const();
| ^^^^^^^^^^^^^^^^^^
For more information about this error, try `rustc --explain E0080`.
好吧,报告的信息可能有点多。由于 Rust 的常量评估和泛型系统仍在快速发展中,这可能会在将来得到改进。
无论如何,我们至少可以在编译时检查单位。
深入了解库
您可以在 units
模块中找到所有提供的内置类型。
如果您想创建自己的良好定义的特殊类型或相关单位,请参阅 macros
模块中的代码生成器。
特性
no_std
/ no_alloc
此库提供无 std 支持和无分配支持。
如果启用 no_std
功能,则 String
和 format!
将从 ::alloc
导出。
如果启用 no_alloc
功能,则无法使用基于字符串的 API,例如 try_cast
和 format_si
。
外部crate功能
const_soft_float
默认情况下禁用,包含在 full
功能中。
此库重新导出 const_soft_float
crate 的常数浮点数学运算,并提供了库的标准关联单位,为这些类型提供常数转换方法。
许可证
本项目受 MIT 许可证 或 Apache 2.0 许可证 许可。
贡献
该项目仍处于早期开发阶段,因此没有严格的贡献流程,您可以随意打开问题或拉取请求!
依赖关系
~56KB