dsn: make `DsnDesign` don't own the constructed `DsnRules` object

This commit is contained in:
Mikolaj Wielgus 2024-03-09 12:54:35 +00:00
parent b661047ca8
commit f8892f64a7
3 changed files with 41 additions and 44 deletions

View File

@ -1,6 +1,6 @@
use std::fmt;
use serde::de::{self, DeserializeSeed, SeqAccess, EnumAccess, VariantAccess, Visitor};
use serde::de::{self, DeserializeSeed, EnumAccess, SeqAccess, VariantAccess, Visitor};
use serde::Deserialize;
use thiserror::Error;
@ -88,9 +88,9 @@ impl<'de> Deserializer<'de> {
fn keyword_lookahead(&self) -> Option<String> {
let mut iter = self.input.chars();
if let Some('(') = iter.next() {
Some(iter
.take_while(|c| c != &' ' && c != &'\r' && c != &'\n')
.collect::<String>()
Some(
iter.take_while(|c| c != &' ' && c != &'\r' && c != &'\n')
.collect::<String>(),
)
} else {
None
@ -387,9 +387,9 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
where
V: Visitor<'de>,
{
let elem_type = self.vec_type.expect(
"fields of type Vec<_> need to have names suffixed with _vec"
);
let elem_type = self
.vec_type
.expect("fields of type Vec<_> need to have names suffixed with _vec");
visitor.visit_seq(ArrayIndices::new(self, elem_type))
}
@ -461,7 +461,10 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
V: Visitor<'de>,
{
self.skip_ws();
visitor.visit_string(self.parse_string().map_err(|err| DeError::ExpectedKeyword)?)
visitor.visit_string(
self.parse_string()
.map_err(|err| DeError::ExpectedKeyword)?,
)
}
fn deserialize_ignored_any<V>(self, _visitor: V) -> Result<V::Value>
@ -515,11 +518,7 @@ impl<'de, 'a> VariantAccess<'de> for Enum<'a, 'de> {
todo!();
}
fn struct_variant<V>(
self,
_fields: &'static [&'static str],
_visitor: V,
) -> Result<V::Value>
fn struct_variant<V>(self, _fields: &'static [&'static str], _visitor: V) -> Result<V::Value>
where
V: Visitor<'de>,
{
@ -554,9 +553,10 @@ impl<'de, 'a> SeqAccess<'de> for ArrayIndices<'a, 'de> {
// anonymous field
seed.deserialize(&mut *self.de).map(Some)
} else {
let lookahead = self.de.keyword_lookahead().ok_or(
DeError::ExpectedOpeningParen(self.elem_type)
)?;
let lookahead = self
.de
.keyword_lookahead()
.ok_or(DeError::ExpectedOpeningParen(self.elem_type))?;
if lookahead == self.elem_type {
// cannot fail, consuming the lookahead
self.de.next().unwrap();

View File

@ -9,7 +9,7 @@ use crate::{
use super::{
de,
rules::Rules,
rules::DsnRules,
structure::{DsnFile, Pcb, Shape},
};
@ -24,7 +24,6 @@ pub enum LoadingError {
#[derive(Debug)]
pub struct DsnDesign {
pcb: Pcb,
rules: Rules,
}
impl DsnDesign {
@ -34,21 +33,22 @@ impl DsnDesign {
.map_err(|err| LoadingError::Syntax(err))?
.pcb;
let rules = Rules::from_pcb(&pcb);
Ok(Self { pcb, rules })
Ok(Self { pcb })
}
pub fn make_layout(&self) -> Layout<&Rules> {
let mut layout = Layout::new(&self.rules);
pub fn make_layout(&self) -> Layout<DsnRules> {
let rules = DsnRules::from_pcb(&self.pcb);
let mut layout = Layout::new(rules);
// mapping of pin id -> net id prepared for adding pins
let pin_nets = HashMap::<String, i64>::from_iter(
self.pcb.network.net_vec
self.pcb
.network
.net_vec
.iter()
.map(|net| {
// resolve the id so we don't work with strings
let net_id = self.rules.net_ids.get(&net.name).unwrap();
let net_id = layout.rules().net_ids.get(&net.name).unwrap();
// take the list of pins
// and for each pin id output (pin id, net id)
@ -85,10 +85,7 @@ impl DsnDesign {
match &padstack.shape_vec[0] {
Shape::Circle(circle) => {
let circle = Circle {
pos: (
(place.x + pin.x) as f64,
-(place.y + pin.y) as f64
).into(),
pos: ((place.x + pin.x) as f64, -(place.y + pin.y) as f64).into(),
r: circle.diameter as f64 / 2.0,
};
@ -114,7 +111,7 @@ impl DsnDesign {
.via_vec
.iter()
.map(|via| {
let net_id = self.rules.net_ids.get(&via.net).unwrap();
let net_id = layout.rules().net_ids.get(&via.net).unwrap();
// find the padstack referenced by this via placement
let padstack = &self
@ -147,12 +144,12 @@ impl DsnDesign {
.collect();
for wire in self.pcb.wiring.wire_vec.iter() {
let net_id = self.rules.net_ids.get(&wire.net).unwrap();
let net_id = *layout.rules().net_ids.get(&wire.net).unwrap();
// add the first coordinate in the wire path as a dot and save its index
let mut prev_index = layout
.add_fixed_dot(FixedDotWeight {
net: *net_id as i64,
net: net_id as i64,
circle: Circle {
pos: (
wire.path.coord_vec[0].x as f64,
@ -168,7 +165,7 @@ impl DsnDesign {
for coord in wire.path.coord_vec.iter().skip(1) {
let index = layout
.add_fixed_dot(FixedDotWeight {
net: *net_id as i64,
net: net_id as i64,
circle: Circle {
pos: (coord.x as f64, -coord.y as f64).into(),
r: wire.path.width as f64 / 2.0,
@ -182,7 +179,7 @@ impl DsnDesign {
prev_index,
index,
FixedSegWeight {
net: *net_id as i64,
net: net_id as i64,
width: wire.path.width as f64,
},
)

View File

@ -5,12 +5,12 @@ use crate::layout::rules::{Conditions, RulesTrait};
use super::structure::Pcb;
#[derive(Debug)]
pub struct Rule {
pub struct DsnRule {
pub width: f64,
pub clearance: f64,
}
impl Rule {
impl DsnRule {
fn from_dsn(rule: &super::structure::Rule) -> Self {
Self {
width: rule.width as f64 / 100.0,
@ -20,10 +20,10 @@ impl Rule {
}
#[derive(Debug)]
pub struct Rules {
structure_rule: Rule,
pub struct DsnRules {
structure_rule: DsnRule,
// net class name -> rule
class_rules: HashMap<String, Rule>,
class_rules: HashMap<String, DsnRule>,
// net names -> net IDs for Layout
pub net_ids: HashMap<String, i64>,
@ -31,7 +31,7 @@ pub struct Rules {
net_id_classes: HashMap<i64, String>,
}
impl Rules {
impl DsnRules {
pub fn from_pcb(pcb: &Pcb) -> Self {
// keeping this as a separate iter pass because it might be moved into a different struct later?
let net_ids = HashMap::from_iter(
@ -54,18 +54,18 @@ impl Rules {
net_id_classes.insert(*net_id, class.name.clone());
}
})
.map(|class| (class.name.clone(), Rule::from_dsn(&class.rule))),
.map(|class| (class.name.clone(), DsnRule::from_dsn(&class.rule))),
);
Self {
structure_rule: Rule::from_dsn(&pcb.structure.rule),
structure_rule: DsnRule::from_dsn(&pcb.structure.rule),
class_rules,
net_ids,
net_id_classes,
}
}
pub fn get_rule(&self, net: i64) -> &Rule {
pub fn get_rule(&self, net: i64) -> &DsnRule {
if let Some(netclass) = self.net_id_classes.get(&net) {
self.class_rules
.get(netclass)
@ -76,7 +76,7 @@ impl Rules {
}
}
impl<'a> RulesTrait for &'a Rules {
impl RulesTrait for DsnRules {
fn clearance(&self, conditions1: &Conditions, conditions2: &Conditions) -> f64 {
let clr1 = self.get_rule(conditions1.net).clearance;
let clr2 = self.get_rule(conditions2.net).clearance;