dsn: add the ability to load planes, polygons and rotated pins

This commit is contained in:
Tomasz Cichoń 2024-03-01 03:52:28 +01:00
parent de21bbaa8e
commit 88180f5f33
2 changed files with 44 additions and 29 deletions

View File

@ -608,7 +608,8 @@ impl<'de, 'a> SeqAccess<'de> for StructFields<'a, 'de> {
} }
} }
// TODO explain this part of empty option detection // check if the next field is "named"
// (saved as `(fieldname value)`)
if let Some(lookahead) = self.de.next_name_lookahead() { if let Some(lookahead) = self.de.next_name_lookahead() {
if lookahead != self.fields[self.current_field] { if lookahead != self.fields[self.current_field] {
if lookahead + "s" != self.fields[self.current_field] { if lookahead + "s" != self.fields[self.current_field] {
@ -620,7 +621,9 @@ impl<'de, 'a> SeqAccess<'de> for StructFields<'a, 'de> {
self.de.next_option_empty_hint = false; self.de.next_option_empty_hint = false;
} }
} else { } else {
self.de.next_option_empty_hint = false; // optional fields must be "named"
// if we see something else assume empty option
self.de.next_option_empty_hint = true;
} }
self.current_field += 1; self.current_field += 1;

View File

@ -1,4 +1,4 @@
use serde::Deserialize; use serde::{Deserialize, Deserializer, de::Error};
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename = "pcb")] #[serde(rename = "pcb")]
@ -55,6 +55,7 @@ pub struct Unit(pub String);
pub struct Structure { pub struct Structure {
pub layers: Vec<Layer>, pub layers: Vec<Layer>,
pub boundary: Boundary, pub boundary: Boundary,
pub plane: Option<Plane>,
pub vias: Vias, pub vias: Vias,
pub rule: Rule, pub rule: Rule,
} }
@ -79,6 +80,13 @@ pub struct Index(pub u32);
#[serde(rename = "boundary")] #[serde(rename = "boundary")]
pub struct Boundary(pub Path); pub struct Boundary(pub Path);
#[derive(Deserialize, Debug)]
#[serde(rename = "plane")]
pub struct Plane {
net: String,
shape: Polygon,
}
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename = "via")] #[serde(rename = "via")]
pub struct Vias { pub struct Vias {
@ -140,11 +148,18 @@ pub struct Outline {
#[serde(rename = "pin")] #[serde(rename = "pin")]
pub struct Pin { pub struct Pin {
pub name: String, pub name: String,
pub rotate: Option<Rotate>,
pub id: String, pub id: String,
pub x: f32, pub x: f32,
pub y: f32, pub y: f32,
} }
#[derive(Deserialize, Debug)]
#[serde(rename = "rotate")]
pub struct Rotate {
pub angle: f32,
}
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename = "padstack")] #[serde(rename = "padstack")]
pub struct Padstack { pub struct Padstack {
@ -229,47 +244,44 @@ pub struct Wire {
#[serde(rename = "type")] #[serde(rename = "type")]
pub struct Type(pub String); pub struct Type(pub String);
#[derive(Deserialize, Debug)] #[derive(Debug)]
#[serde(rename = "unit")]
pub struct Point { pub struct Point {
pub x: f32, pub x: f32,
pub y: f32, pub y: f32,
} }
fn de_points<'de, D>(deserializer: D) -> Result<Vec<Point>, D::Error>
where D: Deserializer<'de>
{
Vec::<f32>::deserialize(deserializer)?
.chunks(2)
.map(|pair| {
let x = pair[0];
let y = *pair.get(1).ok_or(
Error::custom("expected paired x y coordinates, list ended at x")
)?;
Ok(Point { x, y })
})
.collect::<Result<Vec<Point>, D::Error>>()
}
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(from = "FlatPath")] #[serde(rename = "polygon")]
pub struct Path { pub struct Polygon {
pub layer: String, pub layer: String,
pub width: f32, pub width: f32,
#[serde(deserialize_with = "de_points")]
pub coords: Vec<Point>, pub coords: Vec<Point>,
} }
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]
#[serde(rename = "path")] #[serde(rename = "path")]
struct FlatPath { pub struct Path {
pub layer: String, pub layer: String,
pub width: f32, pub width: f32,
pub coords: Vec<f32>, #[serde(deserialize_with = "de_points")]
} pub coords: Vec<Point>,
impl From<FlatPath> for Path {
fn from(flat: FlatPath) -> Path {
Path {
layer: flat.layer,
width: flat.width,
coords: flat
.coords
.chunks(2)
.map(|pair| Point {
x: pair[0],
// it's possible to return an error instead of panicking if this From were TryFrom,
// but I don't think serde will let us grab and inspect it elsewhere
// so annotating this with line/column information later might be difficult?
y: *pair.get(1).expect("unpaired coordinate in path"),
})
.collect(),
}
}
} }
#[derive(Deserialize, Debug)] #[derive(Deserialize, Debug)]