1use crate::registry::RegistryError;
9
10pub fn split_value_unit(s: &str) -> Result<(f64, &str), RegistryError> {
13 let trimmed = s.trim();
14 let split_at = trimmed.find(char::is_whitespace).ok_or_else(|| {
16 RegistryError::ParseError(format!("expected '<value> <unit>', got '{s}'"))
17 })?;
18 let (val_str, rest) = trimmed.split_at(split_at);
19 let unit = rest.trim_start();
20 if unit.is_empty() {
21 return Err(RegistryError::ParseError(format!(
22 "missing unit after value in '{s}'"
23 )));
24 }
25 let value: f64 = val_str
26 .parse()
27 .map_err(|_| RegistryError::ParseError(format!("invalid number '{val_str}'")))?;
28 Ok((value, unit))
29}
30
31#[cfg(test)]
32mod tests {
33 use super::*;
34
35 #[test]
36 fn parses_simple() {
37 assert_eq!(split_value_unit("25 degC").unwrap(), (25.0, "degC"));
38 assert_eq!(split_value_unit("3.5 barg").unwrap(), (3.5, "barg"));
39 assert_eq!(
40 split_value_unit("-1.2e-3 kJ/kmol").unwrap(),
41 (-1.2e-3, "kJ/kmol")
42 );
43 }
44
45 #[test]
46 fn rejects_missing_unit() {
47 assert!(split_value_unit("25").is_err());
48 assert!(split_value_unit("25 ").is_err());
49 }
50
51 #[test]
52 fn rejects_bad_number() {
53 assert!(split_value_unit("abc kPa").is_err());
54 }
55}