1 unstable release
0.1.0 | Mar 2, 2024 |
---|
#1698 in Rust patterns
66KB
1K
SLoC
The ucsi
library
The ucsi
library provides SI-based unit typing system
and zero-cost unit wrapper for values.
You can use the values of these packages for normal arithmetic (since they overload the operators), and then rust's generic engine and ucsi will help you derive their types.
Thanks to rust's powerful type system and static evaluator, ucsi lets you know at compile time what your arithmetic violates, and there's perfect support for constant arithmetic.
At the same time, you can easily create your own types
(see unit!
macro and the macros
module)
that work seamlessly with ucsi's type system.
Quick start
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();
Thanks to rust's const evaluation, the type-casting is compile-time checked!
To clearify the type-casting check, consider the following example:
let s_can_never_be_newton: Value<_, s> = force.cast_const();
The example above cannot compile, and will throw some error like this:
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`.
Well, there's probably a little bit of a lot of information that's being reported. Since rust's const evaluation and generic system is still under rapid development, this could be improved in the future.
Anyway, at least we can check units at compile time.
Dive into the library
You can find all provided built-in types in the units
module.
If you want to create your well-defined special type or associated unit,
see the macros
module for some code generator.
Features
no_std
/ no_alloc
This library offers no-std support and no-alloc support.
If no_std
feature is enabled, String
and format!
will be exported from ::alloc
.
If no_alloc
feature is enabled, string-based api like try_cast
and format_si
cannot be used.
External crate feature
const_soft_float
Disabled by default, included in the full
feature.
This library re-exports the
const_soft_float
crate's constant float mathematical operations,
and the lib's standard associated units offer constant
conversion method for those types.
License
This project is licensed under the MIT License or the Apache 2.0 License.
Contribute
This project is still in early development, so there is no strict contribution process, you can open issues or pull requests as you please!
Dependencies
~56KB