#dimension #const #unit #compile-time #validation #no-alloc

no-std const-units

一个库,允许你在编译时和运行时检查你的数量维度

4 个版本

0.1.3 2023 年 12 月 14 日
0.1.2 2023 年 12 月 14 日
0.1.1 2023 年 12 月 6 日
0.1.0 2023 年 12 月 3 日

#814 in 测试

每月下载 21

MIT 许可证

56KB
1K SLoC

const-units

一个库,允许你在编译时和运行时验证你的数量维度。

警告:使用实验性功能 generic_const_exprsadt_const_params,这些功能已知会导致错误。如果您只对运行时检查感兴趣,请禁用 const 功能。

编译时示例

正常

use const_units::si; // Parses units at compile time
use const_units::Quantity; // Represents a number with a dimension

// Input attometers, return square attometers
fn square_dist(
    x: Quantity<f64, { si("am") }>,
    y: Quantity<f64, { si("am") }>,
) -> Quantity<f64, { si("am^2") }> {
    x.powi::<2>() + y.powi::<2>()
}

// Input attometers, return meters
fn distance(
    x: Quantity<f64, { si("am") }>,
    y: Quantity<f64, { si("am") }>,
) -> Quantity<f64, { si("m") }> {
    square_dist(x, y)
        .powf::<{ (1, 2) }>() // `(1, 2)` represents 1/2
        .convert_to::<{ si("m") }>()
}

assert_eq!(
    distance(Quantity(3.), Quantity(4.)),
    Quantity(0.000_000_000_000_000_005)
);

错误

# use const_units::{Quantity, units::{meter, second, DIMENSIONLESS}};
fn sum(
    x: Quantity<f64, { meter }>,
    y: Quantity<f64, { second }>,
) -> Quantity<f64, DIMENSIONLESS> {
    x + y // You can't add meters and seconds
}

运行时示例

需要 dyn 功能

use const_units::si;
use const_units::DynQuantity; // A quantity with dynamic units stored at runtime alongside the number
use const_units::InconsistentUnits; // The error returned when inconsistent units are used together

fn distance(
    x: DynQuantity<f64>,
    y: DynQuantity<f64>,
) -> DynQuantity<f64> {
    // The addition operator will panic if the units are inconsistent
    (x.powi(2) + y.powi(2))
        .powf((1, 2))
        .convert_to(si("m"))
        .unwrap()
}

fn distance_checked(
    x: DynQuantity<f64>,
    y: DynQuantity<f64>,
) -> Result<DynQuantity<f64>, InconsistentUnits> {
    // You can use checked operators to avoid panicking
    x.powi(2)
        .checked_add(y.powi(2))?
        .powf((1, 2))
        .convert_to(si("m"))
}

assert_eq!(
    distance_checked(DynQuantity(3., si("am")), DynQuantity(4., si("am"))),
    Ok(DynQuantity(0.000_000_000_000_000_005, si("m"))),
);
assert_eq!(
    distance_checked(DynQuantity(3., si("m")), DynQuantity(4., si("m"))),
    Ok(DynQuantity(5., si("m"))),
);
assert!(distance_checked(DynQuantity(3., si("m")), DynQuantity(4., si("s"))).is_err());

no-std

可以通过禁用 std 功能来允许该包在 no-std 环境中运行。这样做将删除将数量直接转换为字符串的便利方法,并防止实现 std::error::Error 时的错误。

依赖项

~650KB
~14K SLoC