mirror of https://codeberg.org/topola/topola.git
chore: cargo fmt
This commit is contained in:
parent
f653a96eb0
commit
5e3ccf2560
|
|
@ -27,9 +27,5 @@ fn attr_content(attrs: &Vec<Attribute>, name: &str) -> Option<String> {
|
||||||
attrs
|
attrs
|
||||||
.iter()
|
.iter()
|
||||||
.find(|attr| attr.path().is_ident(name))
|
.find(|attr| attr.path().is_ident(name))
|
||||||
.and_then(|attr| Some(attr
|
.and_then(|attr| Some(attr.parse_args::<LitStr>().expect("string literal").value()))
|
||||||
.parse_args::<LitStr>()
|
|
||||||
.expect("string literal")
|
|
||||||
.value()
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
use syn::{Data, DeriveInput, Fields, Field};
|
|
||||||
use syn::Type::Path;
|
|
||||||
use syn::ext::IdentExt;
|
use syn::ext::IdentExt;
|
||||||
|
use syn::Type::Path;
|
||||||
|
use syn::{Data, DeriveInput, Field, Fields};
|
||||||
|
|
||||||
use crate::attr_present;
|
|
||||||
use crate::attr_content;
|
use crate::attr_content;
|
||||||
|
use crate::attr_present;
|
||||||
|
|
||||||
pub fn impl_read(input: &DeriveInput) -> TokenStream {
|
pub fn impl_read(input: &DeriveInput) -> TokenStream {
|
||||||
let name = &input.ident;
|
let name = &input.ident;
|
||||||
|
|
@ -24,26 +24,22 @@ pub fn impl_read(input: &DeriveInput) -> TokenStream {
|
||||||
|
|
||||||
fn impl_body(data: &Data) -> TokenStream {
|
fn impl_body(data: &Data) -> TokenStream {
|
||||||
match data {
|
match data {
|
||||||
Data::Struct(data) => {
|
Data::Struct(data) => match &data.fields {
|
||||||
match &data.fields {
|
Fields::Named(fields) => {
|
||||||
Fields::Named(fields) => {
|
let fields = fields.named.iter().map(|field| impl_field(field));
|
||||||
let fields = fields.named.iter().map(|field| {
|
|
||||||
impl_field(field)
|
|
||||||
});
|
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
#(#fields)*
|
#(#fields)*
|
||||||
})
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => unimplemented!()
|
|
||||||
}
|
}
|
||||||
}
|
_ => unimplemented!(),
|
||||||
|
},
|
||||||
Data::Enum(_data) => {
|
Data::Enum(_data) => {
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
_ => unimplemented!()
|
_ => unimplemented!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,7 +67,7 @@ fn impl_field(field: &Field) -> TokenStream {
|
||||||
if ident == "Option" {
|
if ident == "Option" {
|
||||||
return quote! {
|
return quote! {
|
||||||
#name: tokenizer.read_optional(stringify!(#name_str))?,
|
#name: tokenizer.read_optional(stringify!(#name_str))?,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -81,4 +77,3 @@ fn impl_field(field: &Field) -> TokenStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,7 @@ use thiserror::Error;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
board::{mesadata::AccessMesadata, Board},
|
board::{mesadata::AccessMesadata, Board},
|
||||||
drawing::{
|
drawing::{band::BandTermsegIndex, dot::FixedDotIndex, Infringement},
|
||||||
band::BandTermsegIndex,
|
|
||||||
dot::FixedDotIndex,
|
|
||||||
Infringement,
|
|
||||||
},
|
|
||||||
layout::via::ViaWeight,
|
layout::via::ViaWeight,
|
||||||
router::{navmesh::NavmeshError, RouterError, RouterOptions},
|
router::{navmesh::NavmeshError, RouterError, RouterOptions},
|
||||||
triangulation::GetTrianvertexNodeIndex,
|
triangulation::GetTrianvertexNodeIndex,
|
||||||
|
|
@ -99,7 +95,10 @@ impl<M: AccessMesadata> Autorouter<M> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn place_via(&self, weight: ViaWeight) -> Result<PlaceViaExecutionStepper, AutorouterError> {
|
pub fn place_via(
|
||||||
|
&self,
|
||||||
|
weight: ViaWeight,
|
||||||
|
) -> Result<PlaceViaExecutionStepper, AutorouterError> {
|
||||||
PlaceViaExecutionStepper::new(weight)
|
PlaceViaExecutionStepper::new(weight)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,9 +44,9 @@ impl ExecutionStepper {
|
||||||
match autoroute.step(&mut invoker.autorouter)? {
|
match autoroute.step(&mut invoker.autorouter)? {
|
||||||
AutorouteStatus::Running => InvokerStatus::Running,
|
AutorouteStatus::Running => InvokerStatus::Running,
|
||||||
AutorouteStatus::Routed(..) => InvokerStatus::Running,
|
AutorouteStatus::Routed(..) => InvokerStatus::Running,
|
||||||
AutorouteStatus::Finished => InvokerStatus::Finished(
|
AutorouteStatus::Finished => {
|
||||||
"finished autorouting".to_string(),
|
InvokerStatus::Finished("finished autorouting".to_string())
|
||||||
),
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExecutionStepper::PlaceVia(place_via) => {
|
ExecutionStepper::PlaceVia(place_via) => {
|
||||||
|
|
@ -70,10 +70,7 @@ impl ExecutionStepper {
|
||||||
}
|
}
|
||||||
ExecutionStepper::MeasureLength(measure_length) => {
|
ExecutionStepper::MeasureLength(measure_length) => {
|
||||||
let length = measure_length.doit(&mut invoker.autorouter)?;
|
let length = measure_length.doit(&mut invoker.autorouter)?;
|
||||||
InvokerStatus::Finished(format!(
|
InvokerStatus::Finished(format!("Total length of selected bands: {}", length))
|
||||||
"Total length of selected bands: {}",
|
|
||||||
length
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,8 @@ impl Ratsnest {
|
||||||
for layer in 0..layout.drawing().layer_count() {
|
for layer in 0..layout.drawing().layer_count() {
|
||||||
let mut handle_rvw = |maybe_net: Option<usize>, vertex: RatvertexIndex, pos: Point| {
|
let mut handle_rvw = |maybe_net: Option<usize>, vertex: RatvertexIndex, pos: Point| {
|
||||||
if let Some(net) = maybe_net {
|
if let Some(net) = maybe_net {
|
||||||
triangulations.entry((layer, net))
|
triangulations
|
||||||
|
.entry((layer, net))
|
||||||
.or_insert_with(|| Triangulation::new(node_bound))
|
.or_insert_with(|| Triangulation::new(node_bound))
|
||||||
.add_vertex(RatvertexWeight { vertex, pos })?;
|
.add_vertex(RatvertexWeight { vertex, pos })?;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -927,12 +927,15 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
||||||
fn test_if_looses_dont_infringe_each_other(&self) -> bool {
|
fn test_if_looses_dont_infringe_each_other(&self) -> bool {
|
||||||
!self
|
!self
|
||||||
.primitive_nodes()
|
.primitive_nodes()
|
||||||
.filter(|node| matches!(node,
|
.filter(|node| {
|
||||||
PrimitiveIndex::LooseDot(..)
|
matches!(
|
||||||
| PrimitiveIndex::LoneLooseSeg(..)
|
node,
|
||||||
| PrimitiveIndex::SeqLooseSeg(..)
|
PrimitiveIndex::LooseDot(..)
|
||||||
| PrimitiveIndex::LooseBend(..)
|
| PrimitiveIndex::LoneLooseSeg(..)
|
||||||
))
|
| PrimitiveIndex::SeqLooseSeg(..)
|
||||||
|
| PrimitiveIndex::LooseBend(..)
|
||||||
|
)
|
||||||
|
})
|
||||||
.any(|node| {
|
.any(|node| {
|
||||||
self.find_infringement(
|
self.find_infringement(
|
||||||
node,
|
node,
|
||||||
|
|
@ -944,12 +947,15 @@ impl<CW: Copy, R: AccessRules> Drawing<CW, R> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter(|primitive_node| matches!(primitive_node,
|
.filter(|primitive_node| {
|
||||||
PrimitiveIndex::LooseDot(..)
|
matches!(
|
||||||
| PrimitiveIndex::LoneLooseSeg(..)
|
primitive_node,
|
||||||
| PrimitiveIndex::SeqLooseSeg(..)
|
PrimitiveIndex::LooseDot(..)
|
||||||
| PrimitiveIndex::LooseBend(..)
|
| PrimitiveIndex::LoneLooseSeg(..)
|
||||||
)),
|
| PrimitiveIndex::SeqLooseSeg(..)
|
||||||
|
| PrimitiveIndex::LooseBend(..)
|
||||||
|
)
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
.is_some()
|
.is_some()
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -434,10 +434,7 @@ impl<
|
||||||
GeometryLabel::Joined
|
GeometryLabel::Joined
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.map(|ni| {
|
.map(|ni| self.primitive_weight(ni).retag(ni))
|
||||||
self.primitive_weight(ni)
|
|
||||||
.retag(ni)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn seg_joints(&self, seg: SI) -> (DI, DI) {
|
pub fn seg_joints(&self, seg: SI) -> (DI, DI) {
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,8 @@ impl<'a, R: AccessRules> Poly<'a, R> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_apex(&self, dot: FixedDotIndex) -> bool {
|
fn is_apex(&self, dot: FixedDotIndex) -> bool {
|
||||||
!self.layout
|
!self
|
||||||
|
.layout
|
||||||
.drawing()
|
.drawing()
|
||||||
.primitive(dot)
|
.primitive(dot)
|
||||||
.segs()
|
.segs()
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,8 @@ fn cast_point_to_canonical_line(pt: Point, line: CanonicalLine) -> Point {
|
||||||
/ (line.a * line.a + line.b * line.b),
|
/ (line.a * line.a + line.b * line.b),
|
||||||
(line.a * (-line.b * pt.x() + line.a * pt.y()) - line.b * line.c)
|
(line.a * (-line.b * pt.x() + line.a * pt.y()) - line.b * line.c)
|
||||||
/ (line.a * line.a + line.b * line.b),
|
/ (line.a * line.a + line.b * line.b),
|
||||||
).into()
|
)
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tangent_point_pairs(
|
fn tangent_point_pairs(
|
||||||
|
|
|
||||||
|
|
@ -197,10 +197,8 @@ where
|
||||||
|
|
||||||
let zero_score = K::default();
|
let zero_score = K::default();
|
||||||
this.scores.insert(start, zero_score);
|
this.scores.insert(start, zero_score);
|
||||||
this.visit_next.push(MinScored(
|
this.visit_next
|
||||||
strategy.estimate_cost(&this.graph, start),
|
.push(MinScored(strategy.estimate_cost(&this.graph, start), start));
|
||||||
start,
|
|
||||||
));
|
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -131,9 +131,7 @@ impl<'a, R: AccessRules> Draw<'a, R> {
|
||||||
let tangent = self
|
let tangent = self
|
||||||
.guide()
|
.guide()
|
||||||
.head_around_bend_segment(&head, around, cw, width)?;
|
.head_around_bend_segment(&head, around, cw, width)?;
|
||||||
let offset = self
|
let offset = self.guide().head_around_bend_offset(&head, around, width);
|
||||||
.guide()
|
|
||||||
.head_around_bend_offset(&head, around, width);
|
|
||||||
|
|
||||||
self.cane_around(
|
self.cane_around(
|
||||||
head,
|
head,
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,6 @@ pub enum LoadingError {
|
||||||
Parse(#[from] read::ParseErrorContext),
|
Parse(#[from] read::ParseErrorContext),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// This struct is responsible for managing the various Specctra components of a PCB design,
|
/// This struct is responsible for managing the various Specctra components of a PCB design,
|
||||||
/// including parsing the DSN file, handling the resolution, unit of measurement,
|
/// including parsing the DSN file, handling the resolution, unit of measurement,
|
||||||
/// and organizing the PCB's structure, placement, library, network, and wiring.
|
/// and organizing the PCB's structure, placement, library, network, and wiring.
|
||||||
|
|
@ -68,16 +67,16 @@ impl SpecctraDesign {
|
||||||
pub fn get_name(&self) -> &str {
|
pub fn get_name(&self) -> &str {
|
||||||
&self.pcb.name
|
&self.pcb.name
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes the Specctra Session (.ses) file format using the current board layout and mesadata.
|
/// Writes the Specctra Session (.ses) file format using the current board layout and mesadata.
|
||||||
///
|
///
|
||||||
/// This function generates a Specctra SES session file that represents the board's net routing and
|
/// This function generates a Specctra SES session file that represents the board's net routing and
|
||||||
/// writes it to the provided output stream. The session data includes routed nets, wires,
|
/// writes it to the provided output stream. The session data includes routed nets, wires,
|
||||||
/// layers, and other essential information for routing management.
|
/// layers, and other essential information for routing management.
|
||||||
pub fn write_ses(
|
pub fn write_ses(
|
||||||
&self,
|
&self,
|
||||||
board: &Board<SpecctraMesadata>,
|
board: &Board<SpecctraMesadata>,
|
||||||
writer: impl std::io::Write,
|
writer: impl std::io::Write,
|
||||||
) -> Result<(), std::io::Error> {
|
) -> Result<(), std::io::Error> {
|
||||||
let mesadata = board.mesadata();
|
let mesadata = board.mesadata();
|
||||||
let drawing = board.layout().drawing();
|
let drawing = board.layout().drawing();
|
||||||
|
|
@ -150,8 +149,8 @@ impl SpecctraDesign {
|
||||||
structure::NetOut {
|
structure::NetOut {
|
||||||
name: mesadata.net_netname(net).unwrap().to_owned(),
|
name: mesadata.net_netname(net).unwrap().to_owned(),
|
||||||
wire: vec![wire],
|
wire: vec![wire],
|
||||||
via: Vec::new()
|
via: Vec::new(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -193,7 +192,8 @@ impl SpecctraDesign {
|
||||||
)));
|
)));
|
||||||
|
|
||||||
// mapping of pin -> net prepared for adding pins
|
// mapping of pin -> net prepared for adding pins
|
||||||
let pin_nets = self.pcb
|
let pin_nets = self
|
||||||
|
.pcb
|
||||||
.network
|
.network
|
||||||
.nets
|
.nets
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -229,22 +229,15 @@ impl SpecctraDesign {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let place_side_is_front = place.side == "front";
|
let place_side_is_front = place.side == "front";
|
||||||
let get_layer = |board: &Board<SpecctraMesadata>, name: &str| Self::layer(
|
let get_layer = |board: &Board<SpecctraMesadata>, name: &str| {
|
||||||
board,
|
Self::layer(board, &self.pcb.structure.layers, name, place_side_is_front)
|
||||||
&self.pcb.structure.layers,
|
};
|
||||||
name,
|
|
||||||
place_side_is_front,
|
|
||||||
);
|
|
||||||
|
|
||||||
for pin in &image.pins {
|
for pin in &image.pins {
|
||||||
let pinname = format!("{}-{}", place.name, pin.id);
|
let pinname = format!("{}-{}", place.name, pin.id);
|
||||||
let net = pin_nets.get(&pinname).unwrap();
|
let net = pin_nets.get(&pinname).unwrap();
|
||||||
|
|
||||||
let padstack = self
|
let padstack = self.pcb.library.find_padstack_by_name(&pin.name).unwrap();
|
||||||
.pcb
|
|
||||||
.library
|
|
||||||
.find_padstack_by_name(&pin.name)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
for shape in padstack.shapes.iter() {
|
for shape in padstack.shapes.iter() {
|
||||||
match shape {
|
match shape {
|
||||||
|
|
@ -315,14 +308,11 @@ impl SpecctraDesign {
|
||||||
.netname_net(&via.net)
|
.netname_net(&via.net)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let padstack = self
|
let padstack = self.pcb.library.find_padstack_by_name(&via.name).unwrap();
|
||||||
.pcb
|
|
||||||
.library
|
|
||||||
.find_padstack_by_name(&via.name)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let get_layer = |board: &Board<SpecctraMesadata>, name: &str|
|
let get_layer = |board: &Board<SpecctraMesadata>, name: &str| {
|
||||||
Self::layer(board, &self.pcb.structure.layers, name, true);
|
Self::layer(board, &self.pcb.structure.layers, name, true)
|
||||||
|
};
|
||||||
|
|
||||||
for shape in &padstack.shapes {
|
for shape in &padstack.shapes {
|
||||||
match shape {
|
match shape {
|
||||||
|
|
@ -692,12 +682,7 @@ impl SpecctraDesign {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pos(
|
fn pos(place: PointWithRotation, pin: PointWithRotation, x: f64, y: f64) -> Point {
|
||||||
place: PointWithRotation,
|
|
||||||
pin: PointWithRotation,
|
|
||||||
x: f64,
|
|
||||||
y: f64,
|
|
||||||
) -> Point {
|
|
||||||
let pos = (point! {x: x, y: y} + pin.pos).rotate_around_point(pin.rot, pin.pos);
|
let pos = (point! {x: x, y: y} + pin.pos).rotate_around_point(pin.rot, pin.pos);
|
||||||
(pos + place.pos).rotate_around_point(place.rot, place.pos)
|
(pos + place.pos).rotate_around_point(place.rot, place.pos)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//! Module for handling Specctra's mesadata - design rules, as well as layers
|
//! Module for handling Specctra's mesadata - design rules, as well as layers
|
||||||
//! or net properties
|
//! or net properties
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
|
@ -16,7 +16,7 @@ use crate::{
|
||||||
/// the Topola auto-router, in a PCB design process. This struct defines two key design
|
/// the Topola auto-router, in a PCB design process. This struct defines two key design
|
||||||
/// rules: the width of the trace and the minimum clearance between electrical features.
|
/// rules: the width of the trace and the minimum clearance between electrical features.
|
||||||
pub struct SpecctraRule {
|
pub struct SpecctraRule {
|
||||||
/// Specifies the width of the trace (or conductor) in millimeters.
|
/// Specifies the width of the trace (or conductor) in millimeters.
|
||||||
/// This value ensures that the traces meet electrical
|
/// This value ensures that the traces meet electrical
|
||||||
/// and mechanical requirements, such as current-carrying capacity or signal integrity.
|
/// and mechanical requirements, such as current-carrying capacity or signal integrity.
|
||||||
pub width: f64,
|
pub width: f64,
|
||||||
|
|
@ -42,10 +42,9 @@ impl SpecctraRule {
|
||||||
/// This struct encapsulates information about rules for individual nets, net classes,
|
/// This struct encapsulates information about rules for individual nets, net classes,
|
||||||
/// layers, and their corresponding relationships.
|
/// layers, and their corresponding relationships.
|
||||||
pub struct SpecctraMesadata {
|
pub struct SpecctraMesadata {
|
||||||
|
|
||||||
/// The default routing rule applied globally if no specific net class rule is defined.
|
/// The default routing rule applied globally if no specific net class rule is defined.
|
||||||
structure_rule: SpecctraRule,
|
structure_rule: SpecctraRule,
|
||||||
|
|
||||||
// net class name -> rule
|
// net class name -> rule
|
||||||
/// A map from net class names to their specific `SpecctraRule` constraints.
|
/// A map from net class names to their specific `SpecctraRule` constraints.
|
||||||
/// These rules are applied to all nets belonging to the respective net clas
|
/// These rules are applied to all nets belonging to the respective net clas
|
||||||
|
|
@ -67,7 +66,6 @@ pub struct SpecctraMesadata {
|
||||||
net_netclass: HashMap<usize, String>,
|
net_netclass: HashMap<usize, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl SpecctraMesadata {
|
impl SpecctraMesadata {
|
||||||
/// Creates a [`SpecctraMesadata`] instance from a given `Pcb` reference.
|
/// Creates a [`SpecctraMesadata`] instance from a given `Pcb` reference.
|
||||||
///
|
///
|
||||||
|
|
@ -75,10 +73,11 @@ impl SpecctraMesadata {
|
||||||
/// layer-to-layer name mappings, net-to-net name mappings, and net class rules.
|
/// layer-to-layer name mappings, net-to-net name mappings, and net class rules.
|
||||||
pub fn from_pcb(pcb: &Pcb) -> Self {
|
pub fn from_pcb(pcb: &Pcb) -> Self {
|
||||||
let layer_layername = BiHashMap::from_iter(
|
let layer_layername = BiHashMap::from_iter(
|
||||||
pcb.structure.layers
|
pcb.structure
|
||||||
|
.layers
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(index, layer)| (index, layer.name.clone()))
|
.map(|(index, layer)| (index, layer.name.clone())),
|
||||||
);
|
);
|
||||||
|
|
||||||
// keeping this as a separate iter pass because it might be moved into a different struct later?
|
// keeping this as a separate iter pass because it might be moved into a different struct later?
|
||||||
|
|
@ -115,7 +114,9 @@ impl SpecctraMesadata {
|
||||||
if rule.width.is_some() {
|
if rule.width.is_some() {
|
||||||
structure_rule.width = rule.width.unwrap()
|
structure_rule.width = rule.width.unwrap()
|
||||||
}
|
}
|
||||||
structure_rule.clearances.extend_from_slice(&rule.clearances);
|
structure_rule
|
||||||
|
.clearances
|
||||||
|
.extend_from_slice(&rule.clearances);
|
||||||
}
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -129,9 +130,9 @@ impl SpecctraMesadata {
|
||||||
|
|
||||||
/// Retrieves the Specctra routing rule associated with a specified net ID.
|
/// Retrieves the Specctra routing rule associated with a specified net ID.
|
||||||
///
|
///
|
||||||
/// This function looks up the routing rule for a given net ID. It first checks if the net is
|
/// This function looks up the routing rule for a given net ID. It first checks if the net is
|
||||||
/// associated with a net class. If a net class is found, it retrieves the corresponding rule
|
/// associated with a net class. If a net class is found, it retrieves the corresponding rule
|
||||||
/// from the class rules. If no class is associated, or if the class does not have a defined rule,
|
/// from the class rules. If no class is associated, or if the class does not have a defined rule,
|
||||||
/// it defaults to the general structure rule.
|
/// it defaults to the general structure rule.
|
||||||
///
|
///
|
||||||
pub fn get_rule(&self, net: usize) -> &SpecctraRule {
|
pub fn get_rule(&self, net: usize) -> &SpecctraRule {
|
||||||
|
|
|
||||||
|
|
@ -38,26 +38,31 @@ pub struct InputToken {
|
||||||
|
|
||||||
impl InputToken {
|
impl InputToken {
|
||||||
pub fn new(token: ListToken, context: (usize, usize)) -> Self {
|
pub fn new(token: ListToken, context: (usize, usize)) -> Self {
|
||||||
Self {
|
Self { token, context }
|
||||||
token,
|
|
||||||
context,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expect_start(self, name: &'static str) -> Result<(), ParseErrorContext> {
|
pub fn expect_start(self, name: &'static str) -> Result<(), ParseErrorContext> {
|
||||||
self.token.expect_start(name).map_err(|err| err.add_context(self.context))
|
self.token
|
||||||
|
.expect_start(name)
|
||||||
|
.map_err(|err| err.add_context(self.context))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expect_any_start(self) -> Result<String, ParseErrorContext> {
|
pub fn expect_any_start(self) -> Result<String, ParseErrorContext> {
|
||||||
self.token.expect_any_start().map_err(|err| err.add_context(self.context))
|
self.token
|
||||||
|
.expect_any_start()
|
||||||
|
.map_err(|err| err.add_context(self.context))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expect_leaf(self) -> Result<String, ParseErrorContext> {
|
pub fn expect_leaf(self) -> Result<String, ParseErrorContext> {
|
||||||
self.token.expect_leaf().map_err(|err| err.add_context(self.context))
|
self.token
|
||||||
|
.expect_leaf()
|
||||||
|
.map_err(|err| err.add_context(self.context))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expect_end(self) -> Result<(), ParseErrorContext> {
|
pub fn expect_end(self) -> Result<(), ParseErrorContext> {
|
||||||
self.token.expect_end().map_err(|err| err.add_context(self.context))
|
self.token
|
||||||
|
.expect_end()
|
||||||
|
.map_err(|err| err.add_context(self.context))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -191,9 +196,7 @@ impl<R: std::io::BufRead> ListTokenizer<R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn map_context<T>(&self, result: Result<T, ParseError>)
|
fn map_context<T>(&self, result: Result<T, ParseError>) -> Result<T, ParseErrorContext> {
|
||||||
-> Result<T, ParseErrorContext>
|
|
||||||
{
|
|
||||||
result.map_err(|err| self.add_context(err))
|
result.map_err(|err| self.add_context(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -215,7 +218,8 @@ impl<R: std::io::BufRead> ListTokenizer<R> {
|
||||||
Ok(if let Some(chr) = self.peeked_char {
|
Ok(if let Some(chr) = self.peeked_char {
|
||||||
chr
|
chr
|
||||||
} else {
|
} else {
|
||||||
let chr = self.reader
|
let chr = self
|
||||||
|
.reader
|
||||||
.read_char()
|
.read_char()
|
||||||
.transpose()
|
.transpose()
|
||||||
.ok_or(self.add_context(ParseError::Eof))?
|
.ok_or(self.add_context(ParseError::Eof))?
|
||||||
|
|
@ -332,7 +336,10 @@ impl<R: std::io::BufRead> ListTokenizer<R> {
|
||||||
T::read_dsn(self)
|
T::read_dsn(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_named<T: ReadDsn<R>>(&mut self, name: &'static str) -> Result<T, ParseErrorContext> {
|
pub fn read_named<T: ReadDsn<R>>(
|
||||||
|
&mut self,
|
||||||
|
name: &'static str,
|
||||||
|
) -> Result<T, ParseErrorContext> {
|
||||||
self.consume_token()?.expect_start(name)?;
|
self.consume_token()?.expect_start(name)?;
|
||||||
let value = self.read_value::<T>()?;
|
let value = self.read_value::<T>()?;
|
||||||
self.consume_token()?.expect_end()?;
|
self.consume_token()?.expect_end()?;
|
||||||
|
|
|
||||||
|
|
@ -99,9 +99,7 @@ pub struct Structure {
|
||||||
|
|
||||||
// custom impl to handle layers appearing late
|
// custom impl to handle layers appearing late
|
||||||
impl<R: std::io::BufRead> ReadDsn<R> for Structure {
|
impl<R: std::io::BufRead> ReadDsn<R> for Structure {
|
||||||
fn read_dsn(
|
fn read_dsn(tokenizer: &mut ListTokenizer<R>) -> Result<Self, ParseErrorContext> {
|
||||||
tokenizer: &mut ListTokenizer<R>,
|
|
||||||
) -> Result<Self, ParseErrorContext> {
|
|
||||||
let mut value = Self {
|
let mut value = Self {
|
||||||
layers: tokenizer.read_named_array("layer")?,
|
layers: tokenizer.read_named_array("layer")?,
|
||||||
boundary: tokenizer.read_named("boundary")?,
|
boundary: tokenizer.read_named("boundary")?,
|
||||||
|
|
@ -111,7 +109,9 @@ impl<R: std::io::BufRead> ReadDsn<R> for Structure {
|
||||||
rules: tokenizer.read_named_array("rule")?,
|
rules: tokenizer.read_named_array("rule")?,
|
||||||
};
|
};
|
||||||
|
|
||||||
value.layers.append(&mut tokenizer.read_named_array("layer")?);
|
value
|
||||||
|
.layers
|
||||||
|
.append(&mut tokenizer.read_named_array("layer")?);
|
||||||
|
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue