fix: a size worked out from a bare diameter keeps its unit when the design's units change (#716) (#779)

A size typed as a bare diameter now keeps the design's length unit, so it no longer changes when the design's units change. Fixes #716.
This commit is contained in:
semmelrinde authored and GitHub committed 2026-10-13 12:35:25 -04:00
1 parent 8cdefd4cd5
commit dfa9e094cd
7 files changed
+309 -14

No files matched your search

+13
View File
@@ -350,6 +350,17 @@ pub fn is_literal(s: &str) -> bool {
}
}
/// Is the expression a bare number without a unit, like `20` or `-1.5`?
pub fn is_bare_number(s: &str) -> bool {
is_literal(s) && s.trim().trim_start_matches(['-', '+']).trim().parse::<f64>().is_ok()
}
/// The length unit of a design with these units: `mm` unless they name another length unit.
pub fn length_unit_or_mm(units: &str) -> &str {
let u = units.trim();
if unit_info(u).is_some_and(|(k, _)| k == Kind::Length) { u } else { "mm" }
}
struct Parser<'a> {
toks: Vec<Tok>,
pos: usize,
@@ -942,5 +953,7 @@ mod tests {
assert_eq!(rename_reference("10 mm", "mm", "x"), "10 mm");
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)"));
assert_eq!((length_unit_or_mm(" in "), length_unit_or_mm("deg"), length_unit_or_mm("")), ("in", "mm", "mm"));
}
}
+1 -1
View File
@@ -466,7 +466,7 @@ impl Document {
/// in (feature inputs are stored in mm otherwise). Anything else is returned unchanged.
pub fn with_design_unit(&self, e: &str, kind: Kind) -> String {
let u = self.units.trim();
let bare = expr::is_literal(e) && e.trim().trim_start_matches(['-', '+']).trim().parse::<f64>().is_ok();
let bare = expr::is_bare_number(e);
if kind == Kind::Length && bare && !u.is_empty() && u != "mm" && expr::unit_info(u).is_some_and(|(k, _)| k == Kind::Length) {
format!("{} {u}", e.trim())
} else {