use serde::{de::Error, Deserialize, Deserializer}; #[derive(Deserialize, Debug)] pub struct DsnFile { pub pcb: Pcb, } #[derive(Deserialize, Debug)] pub struct Pcb { pub name: String, pub parser: Parser, pub resolution: Resolution, pub unit: String, pub structure: Structure, pub placement: Placement, pub library: Library, pub network: Network, pub wiring: Wiring, } #[derive(Deserialize, Debug)] pub struct Parser { pub string_quote: Option, pub space_in_quoted_tokens: Option, pub host_cad: Option, pub host_version: Option, } #[derive(Deserialize, Debug)] pub struct Resolution { pub unit: String, pub value: u32, } #[derive(Deserialize, Debug)] pub struct Structure { pub layer_vec: Vec, pub boundary: Boundary, pub plane_vec: Vec, pub via: ViaNames, pub rule: Rule, } #[derive(Deserialize, Debug)] pub struct Layer { pub name: String, pub r#type: String, pub property: Property, } #[derive(Deserialize, Debug)] pub struct Property { pub index: usize, } #[derive(Deserialize, Debug)] pub struct Boundary { pub path: Path, } #[derive(Deserialize, Debug)] pub struct Plane { pub net: String, pub polygon: Polygon, } #[derive(Deserialize, Debug)] pub struct ViaNames { pub name_vec: Vec, } #[derive(Deserialize, Debug)] pub struct Placement { pub component_vec: Vec, } #[derive(Deserialize, Debug)] pub struct Component { pub name: String, pub place_vec: Vec, } #[derive(Deserialize, Debug)] pub struct Place { pub name: String, pub x: f32, pub y: f32, pub side: String, pub rotation: f32, pub PN: Option, } #[derive(Deserialize, Debug)] pub struct Library { pub image_vec: Vec, pub padstack_vec: Vec, } #[derive(Deserialize, Debug)] pub struct Image { pub name: String, pub outline_vec: Vec, pub pin_vec: Vec, } #[derive(Deserialize, Debug)] pub struct Outline { pub path: Path, } #[derive(Deserialize, Debug)] pub struct Pin { pub name: String, pub rotate: Option, pub id: String, pub x: f32, pub y: f32, } #[derive(Deserialize, Debug)] pub struct Rotate { pub angle: f32, } #[derive(Deserialize, Debug)] pub struct Padstack { pub name: String, pub shape_vec: Vec, pub attach: bool, } #[derive(Deserialize, Debug)] pub enum Shape { #[serde(rename = "circle")] Circle(Circle), #[serde(rename = "rect")] Rect(Rect), #[serde(rename = "path")] Path(Path), #[serde(rename = "polygon")] Polygon(Polygon), } #[derive(Deserialize, Debug)] pub struct Circle { pub layer: String, pub diameter: u32, } #[derive(Deserialize, Debug)] pub struct Network { pub net_vec: Vec, pub class_vec: Vec, } #[derive(Deserialize, Debug)] // dsn names this "net", but it's a structure unrelated to "net" in wiring or elsewhere pub struct NetPinAssignments { pub name: String, pub pins: Pins, } #[derive(Deserialize, Debug)] pub struct Pins { pub names: Vec, } #[derive(Deserialize, Debug)] pub struct Class { pub name: String, pub net_vec: Vec, pub circuit: Circuit, pub rule: Rule, } #[derive(Deserialize, Debug)] pub struct Circuit { pub use_via: UseVia, } #[derive(Deserialize, Debug)] pub struct UseVia { pub name: String, } #[derive(Deserialize, Debug)] pub struct Wiring { pub wire_vec: Vec, pub via_vec: Vec, } #[derive(Deserialize, Debug)] pub struct Wire { pub path: Path, pub net: String, pub r#type: String, } // structs that appear in multiple places // 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")]. #[derive(Debug)] pub struct Point { pub x: f32, pub y: f32, } // Used to deserialize Vec. fn de_points<'de, D>(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { 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>>() } #[derive(Deserialize, Debug)] pub struct Polygon { pub layer: String, pub width: f32, #[serde(deserialize_with = "de_points")] pub coord_vec: Vec, } #[derive(Deserialize, Debug)] pub struct Path { pub layer: String, pub width: f32, #[serde(deserialize_with = "de_points")] pub coord_vec: Vec, } #[derive(Deserialize, Debug)] pub struct Rect { pub layer: String, pub x1: f32, pub y1: f32, pub x2: f32, pub y2: f32, } #[derive(Deserialize, Debug)] pub struct Via { pub name: String, pub x: i32, pub y: i32, pub net: String, pub r#type: String, } #[derive(Deserialize, Debug)] pub struct Rule { pub width: f32, pub clearance_vec: Vec, } #[derive(Deserialize, Debug)] pub struct Clearance { pub value: f32, pub r#type: Option, }