Accept a unit typed after a space in number fields

Found while testing crates/ui-egui/src/field_math.rs:105 (Parser::factor, unit loop; end() at :109)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
NetterSilver
2026-10-25 11:35:08 +00:00
co-authored by Claude Haiku 5.5
parent 92682728e9
commit 8e8314e273
+23 -1
View File
@@ -102,7 +102,15 @@ impl Parser<'_> {
}
let v = digits.parse::<f64>().ok().filter(|v| v.is_finite())?;
// The unit: letters (px, pt, ms, x), a degree sign, and a percent sign where that is one.
while self.chars.next_if(|c| c.is_ascii_alphabetic() || *c == '°' || (*c == '%' && self.percent_unit)).is_some() {}
// It may follow spaces ("3 px").
let percent_unit = self.percent_unit;
let is_unit = |c: &char| c.is_ascii_alphabetic() || *c == '°' || (*c == '%' && percent_unit);
let mut ahead = self.chars.clone();
while ahead.next_if(|c| c.is_whitespace()).is_some() {}
if ahead.peek().is_some_and(is_unit) {
self.space();
}
while self.chars.next_if(is_unit).is_some() {}
Some(v)
}
@@ -161,3 +169,17 @@ pub fn stepped(from: f64, steps: f64, step: f64) -> f64 {
let v = from + steps * step;
if v.is_finite() { (v * 1e6).round() / 1e6 } else { from }
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn unit_after_a_space() {
assert_eq!(parse("3px", true), Some(Typed::Value(3.0)));
assert_eq!(parse("3 px", true), Some(Typed::Value(3.0)));
assert_eq!(parse("10 °", true), Some(Typed::Value(10.0)));
assert_eq!(parse("50 %", true), Some(Typed::Value(50.0)));
assert_eq!(parse("3 px + 2 px", true), Some(Typed::Value(5.0)));
}
}