diff --git a/src/dsn/de.rs b/src/dsn/de.rs index 3de4c93..af286e7 100644 --- a/src/dsn/de.rs +++ b/src/dsn/de.rs @@ -604,7 +604,9 @@ impl<'de, 'a> SeqAccess<'de> for StructFields<'a, 'de> { self.de.skip_ws(); - let ret = if field_name.ends_with("_vec") { + let ret = if field_name.ends_with("_anonymous") { + seed.deserialize(&mut *self.de).map(Some) + } else if field_name.ends_with("_vec") { self.de.vec_type = field_name.strip_suffix("_vec"); let value = seed.deserialize(&mut *self.de).map(Some); self.de.vec_type = None; diff --git a/src/dsn/structure.rs b/src/dsn/structure.rs index ba9a8db..6a53e8b 100644 --- a/src/dsn/structure.rs +++ b/src/dsn/structure.rs @@ -101,6 +101,7 @@ pub struct Image { pub name: String, pub outline_vec: Vec, pub pin_vec: Vec, + pub keepout_vec: Vec, } #[derive(Deserialize, Debug)] @@ -117,6 +118,12 @@ pub struct Pin { pub y: f32, } +#[derive(Deserialize, Debug)] +pub struct Keepout { + pub idk: String, + pub shape_anonymous: Shape, +} + #[derive(Deserialize, Debug)] pub struct Rotate { pub angle: f32, @@ -145,6 +152,8 @@ pub enum Shape { pub struct Circle { pub layer: String, pub diameter: u32, + #[serde(deserialize_with = "de_point_optional")] + pub offset: Option, } #[derive(Deserialize, Debug)] @@ -200,13 +209,42 @@ pub struct Wire { // This type isn't deserialized as is. Instead, Vec is converted from // what's effectively Vec (with even length) in the file. -// Use #[serde(deserialize_with = "de_points")]. +// Use #[serde(deserialize_with = "de_points")] for Vec +// and #[serde(deserialize_with = "de_point_optional")] for a single Point. + #[derive(Debug)] pub struct Point { pub x: f32, pub y: f32, } +// Used to deserialize Option +fn de_point_optional<'de, D>(deserializer: D) -> Result, D::Error> +where + D: Deserializer<'de>, +{ + let mut vec: Vec = Vec::::deserialize(deserializer)? + .chunks(2) + .map(|pair| { + // 0th index is guaranteed to exist by `.chunks()` + // (it ends iteration instead of emitting an empty Vec) + let x = pair[0]; + // but if the file is malformed we may get an odd number of floats + let y = *pair.get(1).ok_or(Error::custom( + "expected paired x y coordinates, list ended at x", + ))?; + + Ok(Point { x, y }) + }) + .collect::, D::Error>>()?; + + if vec.len() > 1 { + Err(Error::custom("expected a single pair of coordinates")) + } else { + Ok(vec.pop()) + } +} + // Used to deserialize Vec. fn de_points<'de, D>(deserializer: D) -> Result, D::Error> where