Crates.io | runtime_units |
lib.rs | runtime_units |
version | 0.3.0 |
source | src |
created_at | 2024-02-26 03:31:01.796909 |
updated_at | 2024-06-11 20:57:13.457411 |
description | A run-time Rust library for working with units of measurement and conversions between them. |
homepage | |
repository | https://github.com/mattrjackson/runtime_units_rs |
max_upload_size | |
id | 1152985 |
size | 728,772 |
The goal for this library is to serve as a run-time Rust library for working with units of measurement and conversions between them. Most robust units libraries for Rust are designed for compile-time constant analysis. If one of those crates meets your needs, you should probably use one of those instead.
Much of the code (particularly the unit definitions) were adapted from the excellent uom library (https://github.com/iliekturtles/uom). This library was designed to support cases where compile time analysis isn't a great fit. This can presently handle conversions of everything supported by uom except temperature (temperature intervals are supported).
An example of including all units and serialization support:
[dependencies]
runtime_units = { version = "0.3.0", features = ["All", "serde"] }
no_std is supported if the std
feature flag is removed.
Individual unit types are supported as features, allowing you to pare down the library to what you need. Serialization is optionally supported via the serde
feature tag, and utoipa schemas can optionally be generated via the utoipa
tag. By default, only the base SI units are enabled (https://en.wikipedia.org/wiki/SI_base_unit).
This library consists of three sets of data structures:
All available units are contained in the Units
enum. Lists of available units can be easily retrieved from the UnitTypes
enum. For each quantity processed (depending on the features you compile with), a unit enumeration is created for each unit type (e.g. LengthUnit
, EnergyUnit
).
Quantities contain a value (currently restricted to f64), and the unit enumeration mentioned above to store the unit. These are then converted to QuantityBase
. All available quantities can be encapsulated in the Quantities
enum. A struct is created for each quantity (e.g. Length
, Area
), and these contain methods to convert from a Units
, or its own internal unit enumeration. As an example, Length
can convert from a given LengthUnit
, and contains helper methods to convert from its current unit to any of the other enumerations (e.g. to_meters()
, to_kilometers()
, etc.).
Example:
use runtime_units::{Length, Acceleration, UnitTypes, Units, QuantityBase, Time};
fn example()
{
let length = Length::meter(10.0);
let length_cm = length.to_centimeter();
assert_eq!(length, length_cm);
let velocity = Acceleration::meter_per_second_squared(1.0) * Time::second(10.0);
assert_eq!(length / Time::second(1.0), velocity);
let unit = Units::Length(units::LengthUnit::angstrom);
let _ = length.try_convert(unit).unwrap();
// list units available for Length:
for unit in UnitTypes::Length.units()
{
println!("{unit}");
}
let quantity = Quantities::Acceleration(Acceleration::centimeter_per_second_squared(10.0));
assert_eq!(velocity, QuantityBase::from(quantity) * Time::second(100.0));
// Get a unit type from a string
let _units = UnitTypes::Length.to_unit("m").unwrap();
// Different ways to print base units of a quantity
println!("Base Units of Velocity = {}", velocity.definition().unit_string());
println!("Base Units of Acceleration = {}", Acceleration::meter_per_second_squared(1.0).definition().unit_string());
}
Currently conversions on my laptop cost < 1 nsec if converting between the same quantity, and up to 3 nsec using the convert method from Quantity
.
This library is still a work in progress. Expect futher changes to the API as it matures.
Pull requests are welcome. For the most part conversions are based on UOM data.