convert-units 0.1.0

Convert between units of measurement (length, mass, volume, temperature, time, digital, ...) with a fluent API. A faithful port of the convert-units npm package. Zero dependencies.
Documentation
//! Integration tests exercising the public API of `convert-units`.

use convert_units::{convert, describe, list, measures, Error};

fn c(v: f64, from: &str, to: &str) -> f64 {
    convert(v).from(from).unwrap().to(to).unwrap()
}

#[test]
fn round_trips() {
    for (from, to) in [("m", "ft"), ("kg", "lb"), ("l", "gal"), ("C", "F"), ("km/h", "m/s")] {
        let there = c(1.0, from, to);
        let back = c(there, to, from);
        assert!((back - 1.0).abs() < 1e-9, "{from}<->{to} round-trip: {back}");
    }
}

#[test]
fn known_values() {
    assert!((c(1.0, "mi", "km") - 1.6093439485009937).abs() < 1e-12);
    assert_eq!(c(1.0, "kg", "g"), 1000.0);
    assert_eq!(c(1.0, "d", "h").round(), 24.0);
    assert_eq!(c(180.0, "deg", "rad"), std::f64::consts::PI);
}

#[test]
fn errors() {
    assert!(matches!(convert(1.0).from("frobnicate"), Err(Error::UnsupportedUnit(_))));
    assert!(matches!(
        convert(1.0).from("l").unwrap().to("kg"),
        Err(Error::IncompatibleMeasures { .. })
    ));
}

#[test]
fn introspection() {
    assert_eq!(measures().len(), 23);
    assert!(measures().contains(&"temperature"));
    assert_eq!(list(None).len(), 185);
    assert!(describe("frobnicate").is_none());
    let kg = describe("kg").unwrap();
    assert_eq!((kg.measure, kg.system, kg.plural), ("mass", "metric", "Kilograms"));
}