From 8e8314e273a80129beddcf7a93af8ab9b73eb41c Mon Sep 17 00:00:00 2001 From: NetterSilver <133535268+Silvertree2010@users.noreply.github.com> Date: Sun, 25 Oct 2026 11:35:08 +0000 Subject: [PATCH] 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 Co-Authored-By: Claude Sonnet 5.5 --- crates/ui-egui/src/field_math.rs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/crates/ui-egui/src/field_math.rs b/crates/ui-egui/src/field_math.rs index c8318309..f81500e6 100644 --- a/crates/ui-egui/src/field_math.rs +++ b/crates/ui-egui/src/field_math.rs @@ -102,7 +102,15 @@ impl Parser<'_> { } let v = digits.parse::().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))); + } +}