A formula that is a bare number gets the design unit (#9261)

This commit is contained in:
Steve Jason
2026-10-30 06:42:04 +00:00
committed by GitHub
parent 1447bc772a
commit 3d744cc8a2
2 changed files with 19 additions and 2 deletions
+6 -2
View File
@@ -589,9 +589,11 @@ pub fn is_literal(s: &str) -> bool {
}
}
/// Is the expression a bare number without a unit, like `20` or `-1.5`?
/// Is the expression a bare number without a unit, like `20` or `-1.5`? A leading `=` only marks
/// a formula (#4681), so `=20` is the same bare number.
pub fn is_bare_number(s: &str) -> bool {
is_literal(s) && s.trim().trim_start_matches(['-', '+']).trim().parse::<f64>().is_ok()
let number = s.trim().strip_prefix('=').unwrap_or(s);
is_literal(s) && number.trim().trim_start_matches(['-', '+']).trim().parse::<f64>().is_ok()
}
/// Is `s` shaped like a parameter name: a letter or `_`, then letters, digits and `_`? The shape
@@ -1449,6 +1451,8 @@ mod tests {
assert!(is_literal("20") && is_literal("-1.5 in") && is_literal("3 deg"));
assert!(!is_literal("d1") && !is_literal("2 * 3") && !is_literal("2 width"));
assert!(is_bare_number(" -1.5 ") && is_bare_number("+2") && !is_bare_number("20 mm") && !is_bare_number("(2)"));
// A leading `=` only marks a formula (#4681): `=5` is the bare number `5`, not `==5`.
assert!(is_bare_number("=5") && is_bare_number(" = -1.5") && !is_bare_number("=5 mm") && !is_bare_number("==5") && !is_bare_number("=d3"));
assert_eq!((length_unit_or_mm(" in "), length_unit_or_mm("deg"), length_unit_or_mm("")), ("in", "mm", "mm"));
}
+13
View File
@@ -1150,6 +1150,19 @@ mod design_length_tests {
assert_eq!(written("", 5.0), w("mm", "5 mm"));
}
/// A bare number typed as a formula (`=5`) means the design's units like `5` does.
#[test]
fn a_formula_that_is_a_bare_number_gets_the_design_unit() {
let mut doc = Document::new("Units");
doc.units = "in".into();
let length = crate::expr::Kind::Length;
assert_eq!(doc.with_design_unit("5", length), "5 in");
assert_eq!(doc.with_design_unit("=5", length), "=5 in");
assert_eq!(doc.with_design_unit("=5 mm", length), "=5 mm");
let inches = doc.eval(&doc.with_design_unit("=5", length), length).unwrap();
assert!((inches - 127.0).abs() < 1e-9, "{inches}");
}
#[test]
fn the_written_value_reads_back_within_a_micrometre() {
for units in ["mm", "cm", "m", "in", "ft"] {