iridium-units 0.1.0

A high-performance runtime unit-of-measure library for Rust
Documentation
# Getting Started with iridium-units

iridium-units is a Rust library for physical units with runtime dimensional
analysis. It works for anything from kitchen conversions to astrophysics.

## Installation

Add to your `Cargo.toml`:

```toml
[dependencies]
iridium-units = "0.1"
```

## Basic Usage

### Creating Quantities

Quantities are created by multiplying a number by a unit:

```rust
use iridium_units::prelude::*;

// Basic quantities
let distance = 100.0 * M;        // 100 meters
let time = 9.58 * S;             // 9.58 seconds
let mass = 70.0 * KG;            // 70 kilograms

// Derived quantities through arithmetic
let speed = &distance / &time;     // ~10.4 m/s
let energy = 0.5 * &mass * &speed * &speed;  // kinetic energy
```

### Unit Conversion

Convert between compatible units using `.to()`:

```rust
use iridium_units::prelude::*;

let distance = 5.0 * KM;
let in_meters = distance.to(M)?;      // 5000 m
let in_miles = distance.to(MILE)?;     // ~3.1 miles

// Get just the numeric value
let meters_value = distance.to_value(M)?;  // 5000.0
# Ok::<(), iridium_units::error::UnitError>(())
```

### Dimensional Analysis

The library automatically tracks dimensions and prevents incompatible operations:

```rust
use iridium_units::prelude::*;

let distance = 100.0 * M;
let time = 10.0 * S;

// This works — creates velocity
let velocity = &distance / &time;

// This fails at runtime — can't add meters to seconds
let result = distance.checked_add(&time);
assert!(result.is_err());
```

### Parsing Units from Strings

Parse unit strings with flexible syntax:

```rust
use iridium_units::prelude::*;

// Simple units
let meter = parse_unit("m")?;
let kilometer = parse_unit("km")?;

// Composite units
let velocity = parse_unit("m/s")?;
let acceleration = parse_unit("m/s^2")?;
let force = parse_unit("kg*m/s^2")?;

// Unicode support
let area = parse_unit("m²")?;
let micro = parse_unit("µm")?;

// Natural language
let speed = parse_unit("km per hour")?;

// LaTeX notation
let energy = parse_unit("kg m^{2} s^{-2}")?;

// Parse quantities (value + unit)
let distance = parse_quantity("100 km")?;
let wavelength = parse_quantity("500 nm")?;
# Ok::<(), iridium_units::error::UnitError>(())
```

## Unit Systems

iridium-units provides several unit systems:

### SI Units (`systems::si`)

```rust
use iridium_units::systems::si::*;

// Base units
let length = 1.0 * M;      // meter
let time = 1.0 * S;        // second
let mass = 1.0 * KG;       // kilogram
let current = 1.0 * A;     // ampere
let temp = 1.0 * K;        // kelvin

// Derived units
let force = 1.0 * N;       // newton
let energy = 1.0 * J;      // joule
let power = 1.0 * W;       // watt
let frequency = 1.0 * HZ;  // hertz
let pressure = 1.0 * PA;   // pascal

// Prefixed units
let km = 1.0 * KM;         // kilometer
let nm = 1.0 * NM;         // nanometer
let ghz = 1.0 * GHZ;       // gigahertz
```

### Astrophysical Units (`systems::astrophysical`)

```rust
use iridium_units::systems::astrophysical::*;

// Distance
let d1 = 1.0 * PARSEC;       // parsec
let d2 = 1.0 * AU;           // astronomical unit
let d3 = 1.0 * LIGHT_YEAR;   // light year

// Solar/planetary
let mass = 1.0 * SOLAR_MASS;
let radius = 1.0 * SOLAR_RADIUS;
let lum = 1.0 * SOLAR_LUMINOSITY;

// Spectroscopy
let flux = 1.0 * JANSKY;     // Jansky (flux density)
let wave = 1.0 * ANGSTROM;   // Angstrom
```

### CGS Units (`systems::cgs`)

```rust
use iridium_units::systems::cgs::*;

let energy = 1.0 * ERG;      // erg
let force = 1.0 * DYNE;      // dyne
let field = 1.0 * GAUSS;     // gauss
```

### Logarithmic Units (`systems::logarithmic`)

```rust
use iridium_units::systems::logarithmic::*;

let star_mag = 5.0 * MAG;           // magnitude
let signal = 10.0 * DB;             // decibel
let order = 2.0 * DEX;              // dex (order of magnitude)
```

## Equivalencies

Equivalencies enable conversions between different physical dimensions when
there's a physical relationship (like wavelength to frequency). See
[equivalencies.md](equivalencies.md) for full documentation.

```rust
use iridium_units::prelude::*;
use iridium_units::equivalencies::spectral;

// Convert wavelength to frequency
let wavelength = 500.0 * NM;
let frequency = wavelength.to_equiv(HZ, spectral())?;
# Ok::<(), iridium_units::error::UnitError>(())
```

## Physical Constants

Access CODATA 2018 physical constants:

```rust
use iridium_units::constants::*;

let c = SPEED_OF_LIGHT;           // 299792458 m/s
let h = PLANCK_CONSTANT;          // 6.62607015e-34 J·s
let k = BOLTZMANN_CONSTANT;       // 1.380649e-23 J/K
let G = GRAVITATIONAL_CONSTANT;   // 6.67430e-11 m³/(kg·s²)
```

## Error Handling

All fallible operations return `UnitResult<T>`:

```rust
use iridium_units::prelude::*;
use iridium_units::error::UnitError;

let mass = 1.0 * KG;
match mass.to(M) {
    Ok(converted) => println!("Converted: {}", converted),
    Err(UnitError::DimensionMismatch { from, to }) => {
        println!("Cannot convert {} to {}", from, to);
    }
    Err(e) => println!("Error: {}", e),
}
```

## Performance Tips

For processing large datasets, use the batch conversion API:

```rust
use iridium_units::prelude::*;
use iridium_units::quantity::{batch_convert, conversion_factor};

// Convert 10,000 values at once (~80x faster than individual conversion)
let values_km: Vec<f64> = (0..10000).map(|i| i as f64).collect();
let values_m = batch_convert(&values_km, KM, M)?;

// Or get the factor for manual/SIMD operations
let factor = conversion_factor(KM, M)?;
# Ok::<(), iridium_units::error::UnitError>(())
```

## Cookbook

Practical recipes for common tasks.

### Speed, Distance, and Time

```rust
use iridium_units::prelude::*;

// Marathon pace: 42.195 km in 3:30:00
let distance = 42.195 * KM;
let time = 3.5 * H;
let pace = &distance / &time;

let pace_mph = pace.to(MILE / H).unwrap();
println!("Pace: {}", pace_mph);  // ~7.5 mi/h

let pace_ms = pace.to(M / S).unwrap();
println!("Pace: {}", pace_ms);  // ~3.35 m/s
```

### Temperature Conversion

```rust
use iridium_units::prelude::*;

// Boiling point of water
let boiling = 100.0 * DEG_C;
let in_fahrenheit = boiling.to(DEG_F).unwrap();
let in_kelvin = boiling.to(K).unwrap();

assert!((in_fahrenheit.value() - 212.0).abs() < 1e-6);
assert!((in_kelvin.value() - 373.15).abs() < 1e-6);
```

### Force and Pressure

```rust
use iridium_units::prelude::*;

// F = ma
let mass = 75.0 * KG;
let accel = 9.8 * &(M / S.pow(2));
let force = &mass * &accel;

let in_newtons = force.to(N).unwrap();
assert!((in_newtons.value() - 735.0).abs() < 0.1);

// Pressure = Force / Area
let area = 0.5 * &M.pow(2);
let pressure = &force / &area;
let in_pascal = pressure.to(PA).unwrap();
assert!((in_pascal.value() - 1470.0).abs() < 1.0);
```

### Parsing User Input

```rust
use iridium_units::prelude::*;

// Accept units from user input, config files, etc.
let input = "100 km/h";
let speed = parse_quantity(input).unwrap();
let in_ms = speed.to(M / S).unwrap();
println!("{} = {}", input, in_ms);
```

### Custom Units

```rust
use iridium_units::prelude::*;

// Define a custom unit
let furlong = Unit::Base(BaseUnit::new(
    "furlong", "fur", &[],
    Dimension::LENGTH,
    201.168  // meters per furlong
));

// Use it for conversion
let marathon = 42.195 * KM;
let in_furlongs = marathon.to(furlong).unwrap();
println!("{} furlongs", in_furlongs.value());  // ~209.7
```

## Next Steps

- [Equivalencies Guide]equivalencies.md — Converting between different physical domains
- [Unit Systems Reference]unit-systems.md — Complete unit tables
- [Advanced Topics]advanced.md — Custom registries, batch operations, and more