Properties: reject a malformed lineweight instead of setting 0.25 mm (#480) (#580)

Squash of PR #580 by @MarekSpodBiedry.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
MarekSpodBiedryandClaude Opus 5.5 authored and GitHub committed 2026-10-11 13:41:25 -04:00
1 parent fc30f2c2ea
commit b23b45e976
3 files changed
+35 -11

No files matched your search

+1 -1
View File
@@ -107,7 +107,7 @@ pub fn used_layers(d: &cadcraft_doc::Drawing) -> std::collections::HashSet<Strin
set
}
fn parse_lw(v: &Value) -> Option<Lineweight> {
pub(super) fn parse_lw(v: &Value) -> Option<Lineweight> {
if let Some(f) = v.as_f64() {
return Some(Lineweight::Mm100((f * 100.0).round().clamp(0.0, 211.0) as u16));
}
+2 -10
View File
@@ -182,16 +182,7 @@ fn run_set(s: &mut Session, p: &Value) -> Result<Value> {
.get("transparency")
.map(|v| parse_transparency(v).ok_or_else(|| bad("properties.set", "transparency must be ByLayer, ByBlock or a percentage from 0 to 90")))
.transpose()?;
let lw = p.get("lineweight").map(|v| match v.as_str().map(str::to_ascii_lowercase).as_deref() {
Some("bylayer") => Lineweight::ByLayer,
Some("byblock") => Lineweight::ByBlock,
Some("default") => Lineweight::Default,
_ => Lineweight::Mm100(
(v.as_f64().or_else(|| v.as_str().and_then(|s| s.trim_end_matches("mm").trim().parse().ok())).unwrap_or(0.25) * 100.0)
.round()
.clamp(0.0, 211.0) as u16,
),
});
let lw = p.get("lineweight").map(|v| super::layer::parse_lw(v).ok_or_else(|| bad("properties.set", "bad lineweight"))).transpose()?;
let d = s.doc_mut()?;
if let Some(l) = str_param(p, "layer") {
d.ensure_layer(l);
@@ -732,6 +723,7 @@ fn block_dims_using(d: &cadcraft_doc::Drawing, name: &str) -> Vec<(String, cadcr
let uses = match &e.kind {
EntityKind::Dimension(dm) => dm.style.eq_ignore_ascii_case(name),
EntityKind::Leader(l) => l.style.eq_ignore_ascii_case(name),
EntityKind::Tolerance(t) => t.style.eq_ignore_ascii_case(name),
_ => false,
};
if uses {
@@ -0,0 +1,32 @@
//! `properties.set` rejects a lineweight it cannot parse and leaves the object's lineweight alone.
use cadcraft_engine::Session;
use cadcraft_engine::doc::{EntityKind, Handle, Lineweight};
use serde_json::json;
fn lineweight(s: &Session, h: Handle) -> Lineweight {
s.doc().unwrap().entity(h).unwrap().common.lineweight
}
#[test]
fn malformed_lineweight_is_rejected_and_keeps_previous_value() {
let mut s = Session::new();
let r = s.execute("circle", &json!({"center": [0, 0], "radius": 5})).unwrap();
let h = Handle::parse_hex(r["handle"].as_str().unwrap()).unwrap();
let hex = h.hex();
let before = lineweight(&s, h);
assert!(s.execute("properties.set", &json!({"handles": [hex], "lineweight": "notanumber"})).is_err());
assert_eq!(lineweight(&s, h), before);
s.execute("properties.set", &json!({"handles": [hex], "lineweight": 0.70})).unwrap();
assert_eq!(lineweight(&s, h), Lineweight::Mm100(70));
assert!(s.execute("properties.set", &json!({"handles": [hex], "lineweight": "notanumber"})).is_err());
assert_eq!(lineweight(&s, h), Lineweight::Mm100(70));
s.execute("properties.set", &json!({"handles": [hex], "lineweight": "0.35 mm"})).unwrap();
assert_eq!(lineweight(&s, h), Lineweight::Mm100(35));
s.execute("properties.set", &json!({"handles": [hex], "lineweight": "ByBlock"})).unwrap();
assert_eq!(lineweight(&s, h), Lineweight::ByBlock);
assert!(matches!(s.doc().unwrap().entity(h).unwrap().kind, EntityKind::Circle(_)));
}