mirror of https://codeberg.org/topola/topola.git
dsn: add the ability to load planes, polygons and rotated pins
This commit is contained in:
parent
de21bbaa8e
commit
88180f5f33
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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)]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue