| Crates.io | octofhir-ucum |
| lib.rs | octofhir-ucum |
| version | 0.5.1 |
| created_at | 2025-08-02 14:49:53.436243+00 |
| updated_at | 2025-08-02 15:15:49.996187+00 |
| description | UCUM (Unified Code for Units of Measure) library for FHIRPath quantity operations with CLI, WASM, and FHIR integration |
| homepage | https://github.com/octofhir/ucum-rs |
| repository | https://github.com/octofhir/ucum-rs |
| max_upload_size | |
| id | 1778898 |
| size | 640,917 |
High-performance Unified Code for Units of Measure (UCUM) implementation in Rust 2024 edition.
# Add to your project
cargo add octofhir-ucum
# Or use the CLI
cargo install octofhir-ucum
# Example: Convert 100 kPa to mm[Hg]
octofhir-ucum convert --value 100 --from kPa --to mm[Hg]
| Feature | Status | Notes |
|---|---|---|
| Comprehensive Validation | โ | validate() with detailed error reporting |
| Unit Analysis | โ | analyse() with dimensions, factors, properties |
| Unit Arithmetic | โ | unit_multiply(), unit_divide() operations |
| Advanced Search | โ | Text, property, fuzzy, and regex search |
| Property Validation | โ | validate_in_property() for physical quantities |
| Unit Compatibility | โ | is_comparable() for commensurability checking |
| Canonical Forms | โ | get_canonical_units() for normalization |
| Special Unit System | โ | Extensible handlers for temperature, logarithmic units |
| Precision Arithmetic | โ | Optional rust_decimal support for high precision |
| ๐ Model Introspection | โ | get_model(), validate_ucum(), get_properties() |
| ๐ Enhanced Display Names | โ | get_common_display() with prefixed unit support |
| ๐ Advanced Conversion | โ | convert_with_context() with precision control |
| Feature | Status | Notes |
|---|---|---|
| SI base/derived units | โ | Full support with 7-dimensional vectors |
| Customary units | โ | Imperial, US customary, etc. |
| Specialized units | โ | Medical, laboratory, information units |
| Prefix handling | โ | e.g., kPa, mL, ยตg with precision support |
| Expression parsing | โ | Zero-copy architecture with robust error messages |
| Unit conversion | โ | Handles factors, offsets, temperature |
| Temperature support | โ | Celsius, Fahrenheit, Rankine with offsets |
| Performance Optimization | โ | Phase 1 Complete - 40% parsing improvement |
| Feature | Status | Notes |
|---|---|---|
| CLI tool | โ | octofhir-ucum binary |
| WASM support | โ | npm package: @octofhir/ucum-wasm |
| Interactive playground | โ | Svelte 5 web application |
| FHIR integration | โ | FHIR Quantity data type support |
| Property-based tests | โ | proptest |
| Fuzzing | โ | cargo-fuzz targets for parser/eval |
| Test Category | Status | Results |
|---|---|---|
| Overall Conformance | โ | 98.6% (1120/1136 tests passing) |
| Validation tests | โ | 99.5% (1048/1053) |
| Conversion tests | โ ๏ธ | 83.1% (49/59) - acceptable precision differences |
| Division tests | โ | 100% (3/3) - precision arithmetic fixed |
| Multiplication tests | โ | 100% (4/4) |
| Display name tests | โ | 94.1% (16/17) |
Current Performance (v0.5.0 with Unified Optimized Parser):
Performance Optimizations Implemented:
UnitExpr<'a> (zero-copy) and OwnedUnitExpr (owned)parser.rs)Benchmarking Infrastructure: Comprehensive benchmarks track performance across multiple dimensions:
Technical Implementation Notes: The unified parser implementation achieves exceptional performance:
parser.rs - Single high-performance parser with advanced optimizationsThe UCUM library is available as a WebAssembly package for use in JavaScript/TypeScript applications.
# Using npm
npm install @octofhir/ucum-wasm
# Using yarn
yarn add @octofhir/ucum-wasm
# Using pnpm
pnpm add @octofhir/ucum-wasm
import {
start,
validate,
get_unit_info,
convert,
evaluate_expression,
arithmetic,
// Phase 3 functions
get_ucum_model,
get_unit_display_name,
convert_advanced_simple
} from '@octofhir/ucum-wasm';
// Initialize the WASM module
start();
// Validate a UCUM expression
const isValid = validate('mg/dL'); // true
// Get information about a unit
const unitInfo = get_unit_info('mg');
console.log(unitInfo.factor); // 0.000001
console.log(unitInfo.dimensions); // [1, 0, 0, 0, 0, 0, 0]
// Convert between units
const result = convert(100, 'kPa', 'mm[Hg]'); // 750.06...
// Evaluate a UCUM expression
const evalResult = evaluate_expression('mg/dL');
console.log(evalResult.factor); // 0.00001
// Perform arithmetic operations
const arithResult = arithmetic('mg', 'mul', 'mL', 1);
console.log(arithResult.dimensions); // [1, 3, 0, 0, 0, 0, 0]
// Phase 3: Model introspection
const model = get_ucum_model();
console.log(model.version); // '2.1'
console.log(model.total_units); // 312
// Phase 3: Enhanced display names
console.log(get_unit_display_name('kg')); // 'kilogram'
console.log(get_unit_display_name('m/s')); // '(meter) / (second)'
// Phase 3: Advanced conversion with precision
const advResult = convert_advanced_simple(1000, 'g', 'kg', 3);
console.log(advResult.value); // 1.000
console.log(advResult.precision_info); // '3 decimal places'
Phase 3 introduces comprehensive model introspection and advanced conversion capabilities to enhance the UCUM implementation.
use octofhir_ucum_core::{get_model, validate_ucum, get_properties, get_common_display};
// Get model information
let model = get_model();
println!("UCUM Version: {}", model.version); // "2.1"
println!("Total Units: {}", model.units.len()); // 312
println!("Total Prefixes: {}", model.prefixes.len()); // 24
// Validate implementation self-consistency
let issues = validate_ucum();
if issues.is_empty() {
println!("UCUM implementation is valid");
} else {
println!("Issues found: {:?}", issues);
}
// Get all available properties
let properties = get_properties();
println!("Available properties: {}", properties.len()); // 101
// Enhanced display names (handles prefixed units)
println!("{}", get_common_display("kg")); // "kilogram"
println!("{}", get_common_display("cm")); // "centimeter"
println!("{}", get_common_display("m/s")); // "(meter) / (second)"
use octofhir_ucum_core::{
convert_with_context,
AdvancedConversionContext,
DecimalPrecision,
RoundingMode,
TemperatureScale
};
// Create conversion context with precise control
let context = AdvancedConversionContext {
precision: DecimalPrecision::Fixed(3),
rounding: RoundingMode::Nearest,
temperature_scale: TemperatureScale::Celsius,
use_special_units: true,
};
// Convert with advanced precision
let result = convert_with_context(1000.0, "g", "kg", &context)?;
println!("Value: {}", result.value); // 1.000
println!("Precision: {}", result.precision_info); // "3 decimal places"
println!("Used special units: {}", result.used_special_units); // false
// Temperature conversion with special handling
let temp_result = convert_with_context(100.0, "Cel", "K", &context)?;
println!("Value: {}", temp_result.value); // 373.150
println!("Used special units: {}", temp_result.used_special_units); // true
All Phase 3 features are available through the CLI:
# Model introspection
octofhir-ucum model
octofhir-ucum self-validate
octofhir-ucum properties --limit 10
# Enhanced display names
octofhir-ucum display kg # kilogram
octofhir-ucum display "m/s" # (meter) / (second)
# Advanced conversion with precision
octofhir-ucum convert-advanced --value 1000 --from g --to kg --precision 3
octofhir-ucum convert-advanced --value 100 --from Cel --to K --precision 2
Phase 3 functions are fully exposed in the WASM package:
// Model introspection
const model = get_ucum_model();
const validation = validate_ucum_implementation();
const properties = get_ucum_properties();
// Enhanced display names
const displayName = get_unit_display_name('kg');
// Advanced conversion
const result = convert_advanced_simple(1000, 'g', 'kg', 3);
const advancedResult = convert_advanced(100, 'Cel', 'K', {
precision_type: 'fixed',
precision_value: 2,
rounding_mode: 'nearest',
temperature_scale: 'celsius',
use_special_units: true
});
An interactive web-based playground is available to explore the UCUM library's capabilities.
# Navigate to the playground directory
cd playground
# Install dependencies
pnpm install
# Start the development server (use npm due to pnpm script execution issues)
npm run dev
The playground will be available at http://localhost:6000.
The UCUM library provides integration with FHIR (Fast Healthcare Interoperability Resources) through the fhir feature.
# Add to your project
cargo add octofhir-ucum --features fhir
use octofhir_ucum_fhir::{FhirQuantity, convert_quantity, are_equivalent};
// Create a FHIR Quantity with a UCUM code
let quantity = FhirQuantity::with_ucum_code(1000.0, "mg");
// Convert to a different unit
let converted = convert_quantity(&quantity, "g").unwrap();
assert_eq!(converted.value, 1.0);
assert_eq!(converted.code, Some("g".to_string()));
// Check if two quantities are equivalent
let quantity2 = FhirQuantity::with_ucum_code(1.0, "g");
assert!(are_equivalent(&quantity2, &converted).unwrap());
The UCUM library includes fuzzing infrastructure to identify potential bugs and edge cases using cargo-fuzz.
# Install cargo-fuzz
cargo install cargo-fuzz
parse_expression function with arbitrary input stringsevaluate function with valid UCUM expressions# Run the parser fuzzer
cargo fuzz run -p octofhir-ucum-fuzz fuzz_parser
# Run the evaluator fuzzer
cargo fuzz run -p octofhir-ucum-fuzz fuzz_evaluator
For continuous fuzzing, you can set up a CI job that runs the fuzzers for a fixed amount of time:
# Run the parser fuzzer for 5 minutes
cargo fuzz run -p octofhir-ucum-fuzz fuzz_parser -- -max_total_time=300
For more details, see the ucum-fuzz README.
The UCUM library includes validation against the official UCUM test cases from the FHIR/Ucum-java repository to ensure compliance with the UCUM specification.
Our implementation achieves 91.4% conformance to the official UCUM functional test suite:
# Run all official validation tests
cargo test official_tests
# Run with detailed output to see individual test results
cargo test run_official_validation_tests -- --nocapture
# Run tests from the second official test file
cargo test run_official_validation_tests_2 -- --nocapture
We welcome contributions to the UCUM-RS project! This guide will help you get started with development and ensure your contributions align with the project's standards.
Fork and clone the repository:
git clone https://github.com/YOUR_USERNAME/ucum-rs.git
cd ucum-rs
Install dependencies:
wasm-pack for WebAssembly buildspnpm for playground developmentBuild the project:
# Build all workspace crates
cargo build --all
# Build with specific features
cargo build --features cli
cargo build --features wasm
cargo build --features fhir
# Run all tests (recommended before submitting PR)
cargo test --all
# Run tests with output for debugging
cargo test --all -- --nocapture
# Run specific test suites
cargo test official_tests # Official UCUM conformance tests
cargo test test_micro_normalization # UTF-8 handling tests
# Run benchmarks
cargo bench
# Format code (required before commit)
cargo fmt --all
# Check formatting without changes
cargo fmt --all -- --check
# Run linter with strict warnings
cargo clippy --all -- -D warnings
# Pre-publish validation (runs all quality checks)
just publish-prep # or cargo fmt && cargo clippy --all -- -D warnings && cargo test --all
# Generate and open documentation
cargo doc --open --no-deps --all
# Validate documentation examples
cargo test --doc
src/parser.rs)Adding new parser features:
parser.rs maintaining performance optimizationssrc/ast.rs, src/evaluator.rs)UnitExpr<'a> for borrowed data, OwnedUnitExpr for owned datasrc/registry.rs, build.rs)ucum-essence.xmlcargo bench and perfparser_optimized.rs if parser-relatedproptest for edge case discoveryucum-fuzz/ directory#[test]
fn test_new_feature() {
// Test successful case
let result = parse_expression("your_expression").unwrap();
assert_eq!(result, expected_ast);
// Test error cases
assert!(parse_expression("invalid_expression").is_err());
// Test edge cases
assert_eq!(parse_expression(""), Ok(UnitExpr::Numeric(1.0)));
}
cargo fmt (rustfmt) for consistent formattingclippy warnings with cargo clippy --all -- -D warningsmainjust publish-prep or equivalent commandscargo test --all)cargo fmt --all -- --check)cargo clippy --all -- -D warnings)thread_local!)wasm-pack build --target web --features wasmno_std compatibility where possibleCLAUDE.md for development commandscd playground
pnpm install
# Use npm for development due to pnpm script execution issues
npm run dev # Runs on http://localhost:6000
The playground provides a real-time testing environment for UCUM expressions and helps validate user-facing functionality.
src/ โ Core library (parsing, evaluation, registry)src/bin/cli.rs โ Command-line interfacesrc/wasm.rs โ WebAssembly bindings for JavaScript/TypeScript (@octofhir/ucum-wasm)src/fhir.rs โ FHIR integration (FHIR Quantity data type support)ucum-fuzz/ โ Fuzzing infrastructure (cargo-fuzz targets)playground/ โ Interactive web-based playground (Svelte 5)spec/ โ UCUM specification assetsApache-2.0