#![forbid(unsafe_code)]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/welworx/dimvexa/main/docs/brand/icon-256.png",
html_favicon_url = "https://raw.githubusercontent.com/welworx/dimvexa/main/docs/brand/icon-32.png"
)]
use dimvexa_core::{AmbiguousDef, Error, Exactness, Kind, PrefixMode, Registry, Shape, UnitDef};
#[allow(
clippy::unreadable_literal,
clippy::too_many_lines,
clippy::unicode_not_nfc,
missing_docs
)]
mod generated {
use super::{AmbiguousDef, Exactness, Kind, PrefixMode, Shape, UnitDef};
include!(concat!(env!("OUT_DIR"), "/units_generated.rs"));
}
pub use generated::{AMBIGUOUS, DATA_HASH, DATA_VERSION, PACKS, UNITS};
pub fn registry() -> Result<Registry, Error> {
Registry::from_defs(UNITS, AMBIGUOUS)
}
#[must_use]
pub fn data_version() -> String {
format!("v{DATA_VERSION}+{DATA_HASH}")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn table_loads_and_is_reasonably_sized() {
let reg = registry().unwrap();
assert!(reg.len() >= 50, "{}", reg.len());
assert_eq!(reg.len(), UNITS.len());
assert!(DATA_HASH.starts_with("fnv1a64:"));
assert!(PACKS.contains(&"base") && PACKS.contains(&"common"));
}
#[test]
fn every_ambiguous_symbol_is_rejected_with_candidates() {
let reg = registry().unwrap();
for a in AMBIGUOUS {
let err = reg.parse(a.symbol).unwrap_err();
assert_eq!(err.code(), "ambiguous_symbol", "{}", a.symbol);
assert_eq!(err.candidates().len(), a.candidates.len() + a.planned.len());
for c in a.candidates {
assert!(
reg.parse(c).is_ok(),
"candidate {c} of {} must resolve",
a.symbol
);
}
}
for sym in ["ton", "gal", "oz", "pt", "cal", "BTU", "mile", "ppm", "hp"] {
assert!(AMBIGUOUS.iter().any(|a| a.symbol == sym), "{sym}");
}
}
}