From 910ab5b76a2f370040a7e7bc8ad9a34f0cc0ee93 Mon Sep 17 00:00:00 2001 From: Ellen Emilia Anna Zscheile Date: Fri, 31 Jan 2025 14:13:28 +0100 Subject: [PATCH] feat: use topola-rules / put 'AccessRules' into separate crate --- .gitignore | 1 + crates/specctra-core/Cargo.toml | 1 + crates/specctra-core/src/lib.rs | 2 +- crates/specctra-core/src/mesadata.rs | 23 ++-- crates/specctra-core/src/rules.rs | 19 ---- crates/topola-rules/Cargo.toml | 21 ++++ crates/topola-rules/README.md | 3 + crates/topola-rules/src/lib.rs | 163 +++++++++++++++++++++++++++ src/autorouter/ratsnest.rs | 2 +- src/drawing/band.rs | 3 +- src/drawing/bend.rs | 3 +- src/drawing/cane.rs | 3 +- src/drawing/collect.rs | 3 +- src/drawing/dot.rs | 3 +- src/drawing/drawing.rs | 11 +- src/drawing/gear.rs | 3 +- src/drawing/graph.rs | 2 +- src/drawing/guide.rs | 85 +++++++++----- src/drawing/head.rs | 3 +- src/drawing/loose.rs | 3 +- src/drawing/mod.rs | 1 + src/drawing/primitive.rs | 43 ++++--- src/drawing/seg.rs | 3 +- src/geometry/geometry.rs | 2 +- src/layout/layout.rs | 3 +- src/layout/poly.rs | 3 +- src/layout/via.rs | 3 +- src/router/draw.rs | 3 +- src/router/navcord.rs | 2 +- src/router/navcorder.rs | 2 +- src/router/navmesh.rs | 3 +- src/router/route.rs | 4 +- src/router/router.rs | 3 +- src/specctra/mod.rs | 3 + 34 files changed, 317 insertions(+), 118 deletions(-) delete mode 100644 crates/specctra-core/src/rules.rs create mode 100644 crates/topola-rules/Cargo.toml create mode 100644 crates/topola-rules/README.md create mode 100644 crates/topola-rules/src/lib.rs diff --git a/.gitignore b/.gitignore index 1d7190b..0994059 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ fp-info-cache # Lockfiles *.lck +.#* # ---> Topola *.ses diff --git a/crates/specctra-core/Cargo.toml b/crates/specctra-core/Cargo.toml index c1462a9..c289bab 100644 --- a/crates/specctra-core/Cargo.toml +++ b/crates/specctra-core/Cargo.toml @@ -13,6 +13,7 @@ geo-types.workspace = true serde.workspace = true specctra_derive.path = "../specctra_derive" thiserror.workspace = true +topola-rules.path = "../topola-rules" utf8-chars = "3.0" [dependencies.rstar] diff --git a/crates/specctra-core/src/lib.rs b/crates/specctra-core/src/lib.rs index 70eebd9..bfa32a2 100644 --- a/crates/specctra-core/src/lib.rs +++ b/crates/specctra-core/src/lib.rs @@ -8,7 +8,7 @@ pub mod error; pub mod math; pub mod mesadata; pub mod read; -pub mod rules; +pub use topola_rules as rules; pub mod structure; pub mod write; diff --git a/crates/specctra-core/src/mesadata.rs b/crates/specctra-core/src/mesadata.rs index dd51d27..de7ea9d 100644 --- a/crates/specctra-core/src/mesadata.rs +++ b/crates/specctra-core/src/mesadata.rs @@ -9,7 +9,7 @@ use bimap::BiBTreeMap; use std::collections::BTreeMap; use crate::{ - rules::{AccessRules, Conditions}, + rules::{AccessRules, Conditions, OrderedPair}, structure::Pcb, }; @@ -17,7 +17,7 @@ use crate::{ /// /// This trait implements generic function for accessing or modifying different /// compounds of board parts like nets or layers -pub trait AccessMesadata: AccessRules { +pub trait AccessMesadata: AccessRules { /// Renames a layer based on its index. fn bename_layer(&mut self, layer: usize, layername: String); @@ -178,19 +178,16 @@ impl SpecctraMesadata { } impl AccessRules for SpecctraMesadata { - fn clearance(&self, conditions1: &Conditions, conditions2: &Conditions) -> f64 { - let (Some(net1), Some(net2)) = (conditions1.maybe_net, conditions2.maybe_net) else { - return 0.0; - }; + type Scalar = f64; + type ObjectKind = (); - let clr1 = self.get_rule(net1).clearance; - let clr2 = self.get_rule(net2).clearance; + fn clearance(&self, conditions: OrderedPair<&Conditions<'_, ()>>) -> f64 { + let (conditions1, conditions2) = conditions.into(); - if clr1 > clr2 { - clr1 - } else { - clr2 - } + let clr1 = self.get_rule(conditions1.net).clearance; + let clr2 = self.get_rule(conditions2.net).clearance; + + f64::max(clr1, clr2) } fn largest_clearance(&self, _maybe_net: Option) -> f64 { diff --git a/crates/specctra-core/src/rules.rs b/crates/specctra-core/src/rules.rs deleted file mode 100644 index 5d7e6ad..0000000 --- a/crates/specctra-core/src/rules.rs +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-FileCopyrightText: 2024 Topola contributors -// -// SPDX-License-Identifier: MIT - -pub trait GetConditions { - fn conditions(&self) -> Conditions; -} - -#[derive(Debug, Default)] -pub struct Conditions { - pub maybe_net: Option, - pub maybe_region: Option, - pub maybe_layer: Option, -} - -pub trait AccessRules { - fn clearance(&self, conditions1: &Conditions, conditions2: &Conditions) -> f64; - fn largest_clearance(&self, net: Option) -> f64; -} diff --git a/crates/topola-rules/Cargo.toml b/crates/topola-rules/Cargo.toml new file mode 100644 index 0000000..a32dac0 --- /dev/null +++ b/crates/topola-rules/Cargo.toml @@ -0,0 +1,21 @@ +# SPDX-FileCopyrightText: 2024 Topola contributors +# +# SPDX-License-Identifier: MIT OR Apache-2.0 + +[package] +name = "topola-rules" +version = "0.1.1" +edition = "2021" +license = "MIT OR Apache-2.0" +repository = "https://codeberg.org/topola/topola" + +[package.metadata.docs.rs] +features = ["serde"] + +[dependencies] + +[dependencies.serde] +version = "1.0" +features = ["derive", "alloc"] +default-features = false +optional = true diff --git a/crates/topola-rules/README.md b/crates/topola-rules/README.md new file mode 100644 index 0000000..c81f3ec --- /dev/null +++ b/crates/topola-rules/README.md @@ -0,0 +1,3 @@ +# topola-rules + +Generic design rules/clearance handling. diff --git a/crates/topola-rules/src/lib.rs b/crates/topola-rules/src/lib.rs new file mode 100644 index 0000000..0228aa1 --- /dev/null +++ b/crates/topola-rules/src/lib.rs @@ -0,0 +1,163 @@ +// SPDX-FileCopyrightText: 2025 Topola contributors +// +// SPDX-License-Identifier: MIT OR Apache-2.0 +// +//! Generic design rules/clearance handling. + +#![no_std] + +extern crate alloc; + +use alloc::borrow::Cow; +use core::ops; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] +#[cfg_attr(feature = "serde", serde(from = "(T, T)", into = "(T, T)"))] +#[cfg_attr( + feature = "serde", + serde(bound( + deserialize = "T: serde::Deserialize<'de> + Ord", + serialize = "T: serde::Serialize + Clone" + )) +)] +pub struct OrderedPair(T, T); + +impl ops::Index for OrderedPair { + type Output = T; + + #[inline] + fn index(&self, index: bool) -> &T { + if index { &self.1 } else { &self.0 } + } +} + +impl From<(T, T)> for OrderedPair { + fn from(mut x: (T, T)) -> Self { + if x.0 > x.1 { + core::mem::swap(&mut x.0, &mut x.1); + } + let (a, b) = x; + Self(a, b) + } +} + +impl From> for (T, T) { + #[inline(always)] + fn from(OrderedPair(a, b): OrderedPair) -> (T, T) { + (a, b) + } +} + +#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] +pub struct Conditions<'a, K> { + pub net: usize, + + #[cfg_attr(feature = "serde", serde(borrow))] + pub maybe_region: Option>, + + #[cfg_attr(feature = "serde", serde(borrow))] + pub maybe_layer: Option>, + + pub kind: K, +} + +impl Conditions<'_, K> { + #[inline] + pub fn ref_(&self) -> Conditions<'_, K> { + Conditions { + net: self.net, + maybe_region: self.maybe_region.as_ref().map(|i| Cow::Borrowed(&**i)), + maybe_layer: self.maybe_layer.as_ref().map(|i| Cow::Borrowed(&**i)), + kind: self.kind, + } + } +} + +pub trait GetConditions<'a>: Sized { + type ObjectKind: Copy + Eq; + + #[inline(always)] + fn conditions(self) -> Option> { + None + } +} + +impl<'a, K: Copy + Eq> GetConditions<'a> for &'a Conditions<'_, K> { + type ObjectKind = K; + + #[inline] + fn conditions(self) -> Option> { + Some(self.ref_()) + } +} + +impl<'a, T: Copy + GetConditions<'a>> GetConditions<'a> for &T { + type ObjectKind = >::ObjectKind; + + #[inline(always)] + fn conditions(self) -> Option>::ObjectKind>> { + T::conditions(*self) + } +} + +pub trait GetWidth { + type Scalar: Copy; + + fn width(&self) -> Self::Scalar; +} + +impl GetWidth for &T { + type Scalar = ::Scalar; + + #[inline(always)] + fn width(&self) -> ::Scalar { + T::width(*self) + } +} + +pub trait AccessRules { + type Scalar: Copy + core::ops::Add + core::iter::Sum; + type ObjectKind: Copy + Eq; + + fn clearance(&self, conditions: OrderedPair<&Conditions<'_, Self::ObjectKind>>) + -> Self::Scalar; + fn largest_clearance(&self, maybe_net: Option) -> Self::Scalar; +} + +impl AccessRules for &T { + type Scalar = ::Scalar; + type ObjectKind = ::ObjectKind; + + #[inline(always)] + fn clearance( + &self, + conditions: OrderedPair<&Conditions<'_, ::ObjectKind>>, + ) -> ::Scalar { + T::clearance(*self, conditions) + } + + #[inline(always)] + fn largest_clearance(&self, maybe_net: Option) -> ::Scalar { + T::largest_clearance(*self, maybe_net) + } +} + +impl AccessRules for alloc::sync::Arc { + type Scalar = ::Scalar; + type ObjectKind = ::ObjectKind; + + #[inline(always)] + fn clearance( + &self, + conditions: OrderedPair<&Conditions<'_, ::ObjectKind>>, + ) -> ::Scalar { + T::clearance(self, conditions) + } + + #[inline(always)] + fn largest_clearance(&self, maybe_net: Option) -> ::Scalar { + T::largest_clearance(self, maybe_net) + } +} diff --git a/src/autorouter/ratsnest.rs b/src/autorouter/ratsnest.rs index f500124..61ef86a 100644 --- a/src/autorouter/ratsnest.rs +++ b/src/autorouter/ratsnest.rs @@ -25,7 +25,7 @@ use crate::{ dot::FixedDotIndex, graph::{GetMaybeNet, MakePrimitive, PrimitiveIndex}, primitive::MakePrimitiveShape, - rules::AccessRules, + AccessRules, }, geometry::shape::AccessShape, graph::{GenericIndex, GetPetgraphIndex}, diff --git a/src/drawing/band.rs b/src/drawing/band.rs index 2bcd89b..2d8ae2b 100644 --- a/src/drawing/band.rs +++ b/src/drawing/band.rs @@ -15,9 +15,8 @@ use super::{ graph::MakePrimitive, loose::{GetPrevNextLoose, LooseIndex}, primitive::MakePrimitiveShape, - rules::AccessRules, seg::{LoneLooseSegIndex, SeqLooseSegIndex}, - Drawing, + AccessRules, Drawing, }; #[derive(Clone, Copy, Debug)] diff --git a/src/drawing/bend.rs b/src/drawing/bend.rs index 7759ec1..82aa9a9 100644 --- a/src/drawing/bend.rs +++ b/src/drawing/bend.rs @@ -8,8 +8,7 @@ use crate::{ drawing::{ graph::{GetLayer, GetMaybeNet, MakePrimitive, PrimitiveIndex, PrimitiveWeight, Retag}, primitive::{GenericPrimitive, Primitive}, - rules::AccessRules, - Drawing, + AccessRules, Drawing, }, geometry::{GetOffset, GetWidth, SetOffset}, graph::{GenericIndex, GetPetgraphIndex}, diff --git a/src/drawing/cane.rs b/src/drawing/cane.rs index 71481a5..b2d7abb 100644 --- a/src/drawing/cane.rs +++ b/src/drawing/cane.rs @@ -7,9 +7,8 @@ use super::{ dot::LooseDotIndex, graph::PrimitiveIndex, primitive::{GetInterior, GetJoints, GetOtherJoint, LooseBend, LooseDot}, - rules::AccessRules, seg::SeqLooseSegIndex, - Drawing, + AccessRules, Drawing, }; /// A cane is a sequence consisting of a seg followed by a dot followed by a diff --git a/src/drawing/collect.rs b/src/drawing/collect.rs index c641a71..a3a2661 100644 --- a/src/drawing/collect.rs +++ b/src/drawing/collect.rs @@ -11,8 +11,7 @@ use super::{ graph::PrimitiveIndex, loose::{GetPrevNextLoose, LooseIndex}, primitive::{GetInnerOuter, GetJoints}, - rules::AccessRules, - Drawing, + AccessRules, Drawing, }; pub trait Collect { diff --git a/src/drawing/dot.rs b/src/drawing/dot.rs index 87ab230..4ee0d3c 100644 --- a/src/drawing/dot.rs +++ b/src/drawing/dot.rs @@ -11,8 +11,7 @@ use crate::{ drawing::{ graph::{GetLayer, GetMaybeNet, MakePrimitive, PrimitiveIndex, PrimitiveWeight, Retag}, primitive::{GenericPrimitive, Primitive}, - rules::AccessRules, - Drawing, + AccessRules, Drawing, }, geometry::{GetSetPos, GetWidth}, graph::{GenericIndex, GetPetgraphIndex}, diff --git a/src/drawing/drawing.rs b/src/drawing/drawing.rs index 7cf45ab..3453114 100644 --- a/src/drawing/drawing.rs +++ b/src/drawing/drawing.rs @@ -36,11 +36,12 @@ use crate::{ GenericPrimitive, GetCore, GetInnerOuter, GetJoints, GetLimbs, GetOtherJoint, MakePrimitiveShape, }, - rules::{AccessRules, GetConditions}, + rules::GetConditions, seg::{ FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SegIndex, SegWeight, SeqLooseSegIndex, SeqLooseSegWeight, }, + AccessRules, }, graph::MakeRef, }; @@ -982,8 +983,12 @@ impl Drawing { let epsilon = 1.0; inflated_shape = node.primitive(self).shape().inflate( - (self.rules.clearance(&conditions, &infringee_conditions) - epsilon) - .clamp(0.0, f64::INFINITY), + match (&conditions, infringee_conditions) { + (None, _) | (_, None) => 0.0, + (Some(lhs), Some(rhs)) => (self.rules.clearance((lhs, &rhs).into()) + - epsilon) + .clamp(0.0, f64::INFINITY), + }, ); inflated_shape diff --git a/src/drawing/gear.rs b/src/drawing/gear.rs index 5804afc..26a5285 100644 --- a/src/drawing/gear.rs +++ b/src/drawing/gear.rs @@ -11,8 +11,7 @@ use crate::{ dot::FixedDotIndex, graph::{MakePrimitive, PrimitiveIndex}, primitive::{FixedBend, FixedDot, GetFirstGear, GetInnerOuter, LooseBend, Primitive}, - rules::AccessRules, - Drawing, + AccessRules, Drawing, }, graph::{GetPetgraphIndex, MakeRef}, }; diff --git a/src/drawing/graph.rs b/src/drawing/graph.rs index 944c1ef..6a18283 100644 --- a/src/drawing/graph.rs +++ b/src/drawing/graph.rs @@ -11,11 +11,11 @@ use super::{ bend::{FixedBendIndex, FixedBendWeight, LooseBendIndex, LooseBendWeight}, dot::{FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight}, primitive::Primitive, - rules::AccessRules, seg::{ FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SeqLooseSegIndex, SeqLooseSegWeight, }, + AccessRules, }; #[enum_dispatch] diff --git a/src/drawing/guide.rs b/src/drawing/guide.rs index 51dde74..dcaa033 100644 --- a/src/drawing/guide.rs +++ b/src/drawing/guide.rs @@ -18,8 +18,8 @@ use super::{ graph::{MakePrimitive, PrimitiveIndex}, head::{BareHead, CaneHead, GetFace, Head}, primitive::{GetCore, GetInnerOuter, GetJoints, GetOtherJoint, GetWeight, MakePrimitiveShape}, - rules::{AccessRules, Conditions, GetConditions}, - Drawing, + rules::{Conditions, GetConditions}, + AccessRules, Drawing, }; pub trait Guide { @@ -97,7 +97,8 @@ impl Guide for Drawing { width: f64, ) -> Result<(Line, Line), NoTangents> { let from_circle = self.head_circle(head, width); - let to_circle = self.dot_circle(around, width, &self.conditions(head.face().into())); + let to_circle = + self.dot_circle(around, width, self.conditions(head.face().into()).as_ref()); let from_cw = self.head_cw(head); let tangents: Vec = @@ -113,16 +114,17 @@ impl Guide for Drawing { width: f64, ) -> Result { let from_circle = self.head_circle(head, width); - let to_circle = self.dot_circle(around, width, &self.conditions(head.face().into())); + let to_circle = + self.dot_circle(around, width, self.conditions(head.face().into()).as_ref()); let from_cw = self.head_cw(head); math::tangent_segment(from_circle, from_cw, to_circle, Some(cw)) } fn head_around_dot_offset(&self, head: &Head, around: DotIndex, _width: f64) -> f64 { - self.rules().clearance( - &self.conditions(around.into()), - &self.conditions(head.face().into()), + self.clearance( + self.conditions(around.into()).as_ref(), + self.conditions(head.face().into()).as_ref(), ) } @@ -133,7 +135,8 @@ impl Guide for Drawing { width: f64, ) -> Result<(Line, Line), NoTangents> { let from_circle = self.head_circle(head, width); - let to_circle = self.bend_circle(around, width, &self.conditions(head.face().into())); + let to_circle = + self.bend_circle(around, width, self.conditions(head.face().into()).as_ref()); let from_cw = self.head_cw(head); let tangents: Vec = @@ -149,16 +152,17 @@ impl Guide for Drawing { width: f64, ) -> Result { let from_circle = self.head_circle(head, width); - let to_circle = self.bend_circle(around, width, &self.conditions(head.face().into())); + let to_circle = + self.bend_circle(around, width, self.conditions(head.face().into()).as_ref()); let from_cw = self.head_cw(head); math::tangent_segment(from_circle, from_cw, to_circle, Some(cw)) } fn head_around_bend_offset(&self, head: &Head, around: BendIndex, _width: f64) -> f64 { - self.rules().clearance( - &self.conditions(head.face().into()), - &self.conditions(around.into()), + self.clearance( + self.conditions(head.face().into()).as_ref(), + self.conditions(around.into()).as_ref(), ) } @@ -196,18 +200,37 @@ impl Guide for Drawing { } trait GuidePrivate { + fn clearance(&self, lhs: Option<&Conditions<'_, ()>>, rhs: Option<&Conditions<'_, ()>>) -> f64; + fn head_circle(&self, head: &Head, width: f64) -> Circle; - fn bend_circle(&self, bend: BendIndex, width: f64, guide_conditions: &Conditions) -> Circle; + fn bend_circle( + &self, + bend: BendIndex, + width: f64, + guide_conditions: Option<&Conditions<'_, ()>>, + ) -> Circle; - fn dot_circle(&self, dot: DotIndex, width: f64, guide_conditions: &Conditions) -> Circle; + fn dot_circle( + &self, + dot: DotIndex, + width: f64, + guide_conditions: Option<&Conditions<'_, ()>>, + ) -> Circle; fn rear(&self, head: CaneHead) -> DotIndex; - fn conditions(&self, node: PrimitiveIndex) -> Conditions; + fn conditions(&self, node: PrimitiveIndex) -> Option>; } impl GuidePrivate for Drawing { + fn clearance(&self, lhs: Option<&Conditions<'_, ()>>, rhs: Option<&Conditions<'_, ()>>) -> f64 { + match (lhs, rhs) { + (None, _) | (_, None) => 0.0, + (Some(lhs), Some(rhs)) => self.rules().clearance((lhs, rhs).into()), + } + } + fn head_circle(&self, head: &Head, width: f64) -> Circle { match *head { Head::Bare(head) => Circle { @@ -216,19 +239,28 @@ impl GuidePrivate for Drawing { }, Head::Cane(head) => { if let Some(inner) = self.primitive(head.cane.bend).inner() { - self.bend_circle(inner.into(), width, &self.conditions(head.face().into())) + self.bend_circle( + inner.into(), + width, + self.conditions(head.face().into()).as_ref(), + ) } else { self.dot_circle( self.primitive(head.cane.bend).core().into(), width, - &self.conditions(head.face().into()), + self.conditions(head.face().into()).as_ref(), ) } } } } - fn bend_circle(&self, bend: BendIndex, width: f64, guide_conditions: &Conditions) -> Circle { + fn bend_circle( + &self, + bend: BendIndex, + width: f64, + guide_conditions: Option<&Conditions<'_, ()>>, + ) -> Circle { let outer_circle = match bend.primitive(self).shape() { PrimitiveShape::Bend(shape) => shape.outer_circle(), _ => unreachable!(), @@ -238,21 +270,22 @@ impl GuidePrivate for Drawing { pos: outer_circle.pos, r: outer_circle.r + width / 2.0 - + self - .rules() - .clearance(&self.conditions(bend.into()), guide_conditions), + + self.clearance(self.conditions(bend.into()).as_ref(), guide_conditions), } } - fn dot_circle(&self, dot: DotIndex, width: f64, guide_conditions: &Conditions) -> Circle { + fn dot_circle( + &self, + dot: DotIndex, + width: f64, + guide_conditions: Option<&Conditions<'_, ()>>, + ) -> Circle { let shape = dot.primitive(self).shape(); Circle { pos: shape.center(), r: shape.width() / 2.0 + width / 2.0 - + self - .rules() - .clearance(&self.conditions(dot.into()), guide_conditions), + + self.clearance(self.conditions(dot.into()).as_ref(), guide_conditions), } } @@ -261,7 +294,7 @@ impl GuidePrivate for Drawing { .other_joint(head.cane.dot.into()) } - fn conditions(&self, node: PrimitiveIndex) -> Conditions { + fn conditions(&self, node: PrimitiveIndex) -> Option> { node.primitive(self).conditions() } } diff --git a/src/drawing/head.rs b/src/drawing/head.rs index 2a08618..99ea9e0 100644 --- a/src/drawing/head.rs +++ b/src/drawing/head.rs @@ -10,8 +10,7 @@ use super::{ cane::Cane, dot::{DotIndex, FixedDotIndex, LooseDotIndex}, primitive::MakePrimitiveShape, - rules::AccessRules, - Drawing, + AccessRules, Drawing, }; #[enum_dispatch] diff --git a/src/drawing/loose.rs b/src/drawing/loose.rs index 0003891..7579c62 100644 --- a/src/drawing/loose.rs +++ b/src/drawing/loose.rs @@ -13,12 +13,11 @@ use crate::{ graph::{MakePrimitive, PrimitiveIndex}, primitive::{GetJoints, LoneLooseSeg, LooseBend, LooseDot, Primitive, SeqLooseSeg}, seg::{LoneLooseSegIndex, SeqLooseSegIndex}, + AccessRules, }, graph::GetPetgraphIndex, }; -use super::rules::AccessRules; - #[enum_dispatch] pub trait GetPrevNextLoose { fn next_loose(&self, maybe_prev: Option) -> Option; diff --git a/src/drawing/mod.rs b/src/drawing/mod.rs index 4b3ef35..ad5db78 100644 --- a/src/drawing/mod.rs +++ b/src/drawing/mod.rs @@ -15,6 +15,7 @@ mod guide; pub mod head; pub mod loose; pub mod primitive; +pub use crate::specctra::AccessRules; pub use specctra_core::rules; pub mod seg; diff --git a/src/drawing/primitive.rs b/src/drawing/primitive.rs index 2170ee0..235de20 100644 --- a/src/drawing/primitive.rs +++ b/src/drawing/primitive.rs @@ -11,13 +11,13 @@ use crate::{ dot::{DotIndex, DotWeight, FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight}, graph::{GetLayer, GetMaybeNet, PrimitiveIndex, PrimitiveWeight, Retag}, seg::{FixedSegWeight, LoneLooseSegWeight, SegIndex, SeqLooseSegIndex, SeqLooseSegWeight}, - Drawing, + AccessRules, Drawing, }, geometry::{primitive::PrimitiveShape, GenericNode, GetOffset, GetWidth}, graph::{GenericIndex, GetPetgraphIndex}, }; -use specctra_core::rules::{AccessRules, Conditions, GetConditions}; +use specctra_core::rules::{Conditions, GetConditions}; #[enum_dispatch] pub trait GetDrawing<'a, R: AccessRules> { @@ -171,16 +171,20 @@ pub enum Primitive<'a, CW: Copy, R: AccessRules> { LooseBend(LooseBend<'a, CW, R>), } -impl<'a, CW: Copy, R: AccessRules> specctra_core::rules::GetConditions for Primitive<'a, CW, R> { - fn conditions(&self) -> specctra_core::rules::Conditions { +impl<'a, CW: Copy, R: AccessRules> specctra_core::rules::GetConditions<'a> + for &Primitive<'a, CW, R> +{ + type ObjectKind = (); + + fn conditions(self) -> Option> { match self { - Self::FixedDot(x) => x.conditions(), - Self::LooseDot(x) => x.conditions(), - Self::FixedSeg(x) => x.conditions(), - Self::LoneLooseSeg(x) => x.conditions(), - Self::SeqLooseSeg(x) => x.conditions(), - Self::FixedBend(x) => x.conditions(), - Self::LooseBend(x) => x.conditions(), + Primitive::FixedDot(x) => x.conditions(), + Primitive::LooseDot(x) => x.conditions(), + Primitive::FixedSeg(x) => x.conditions(), + Primitive::LoneLooseSeg(x) => x.conditions(), + Primitive::SeqLooseSeg(x) => x.conditions(), + Primitive::FixedBend(x) => x.conditions(), + Primitive::LooseBend(x) => x.conditions(), } } } @@ -244,16 +248,19 @@ where } } -impl<'a, W, CW: Copy, R: AccessRules> GetConditions for GenericPrimitive<'a, W, CW, R> +impl<'a, W, CW: Copy, R: AccessRules> GetConditions<'a> for &GenericPrimitive<'a, W, CW, R> where GenericPrimitive<'a, W, CW, R>: GetMaybeNet, { - fn conditions(&self) -> Conditions { - Conditions { - maybe_net: self.maybe_net(), - maybe_region: Some("A".to_string()), - maybe_layer: Some("F.Cu".to_string()), - } + type ObjectKind = (); + + fn conditions(self) -> Option> { + self.maybe_net().map(|net| Conditions { + net, + maybe_region: Some("A".into()), + maybe_layer: Some("F.Cu".into()), + kind: (), + }) } } diff --git a/src/drawing/seg.rs b/src/drawing/seg.rs index 5dade7a..c612749 100644 --- a/src/drawing/seg.rs +++ b/src/drawing/seg.rs @@ -8,8 +8,7 @@ use crate::{ drawing::{ graph::{GetLayer, GetMaybeNet, MakePrimitive, PrimitiveIndex, PrimitiveWeight, Retag}, primitive::{GenericPrimitive, Primitive}, - rules::AccessRules, - Drawing, + AccessRules, Drawing, }, geometry::GetWidth, graph::{GenericIndex, GetPetgraphIndex}, diff --git a/src/geometry/geometry.rs b/src/geometry/geometry.rs index 4eb2192..8645993 100644 --- a/src/geometry/geometry.rs +++ b/src/geometry/geometry.rs @@ -18,8 +18,8 @@ use crate::{ dot::DotWeight, graph::{PrimitiveWeight, Retag}, primitive::Primitive, - rules::AccessRules, seg::SegWeight, + AccessRules, }, geometry::{ compound::ManageCompounds, diff --git a/src/layout/layout.rs b/src/layout/layout.rs index 27b4432..9db7859 100644 --- a/src/layout/layout.rs +++ b/src/layout/layout.rs @@ -16,12 +16,11 @@ use crate::{ gear::GearIndex, graph::{GetMaybeNet, IsInLayer, MakePrimitive, PrimitiveIndex, PrimitiveWeight}, primitive::MakePrimitiveShape, - rules::AccessRules, seg::{ FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SegIndex, SegWeight, SeqLooseSegIndex, SeqLooseSegWeight, }, - Cane, Drawing, DrawingEdit, DrawingException, Infringement, + AccessRules, Cane, Drawing, DrawingEdit, DrawingException, Infringement, }, geometry::{edit::ApplyGeometryEdit, shape::Shape, GenericNode}, graph::{GenericIndex, GetPetgraphIndex}, diff --git a/src/layout/poly.rs b/src/layout/poly.rs index 89ea4a7..f247922 100644 --- a/src/layout/poly.rs +++ b/src/layout/poly.rs @@ -13,9 +13,8 @@ use crate::{ dot::FixedDotIndex, graph::{GetLayer, GetMaybeNet, PrimitiveIndex}, primitive::GetLimbs, - rules::AccessRules, seg::SegIndex, - Drawing, + AccessRules, Drawing, }, geometry::GetSetPos, graph::{GenericIndex, GetPetgraphIndex}, diff --git a/src/layout/via.rs b/src/layout/via.rs index dbfc2ec..61d6aaa 100644 --- a/src/layout/via.rs +++ b/src/layout/via.rs @@ -10,8 +10,7 @@ use crate::{ drawing::{ graph::{GetMaybeNet, IsInLayer}, primitive::MakePrimitiveShape, - rules::AccessRules, - Drawing, + AccessRules, Drawing, }, geometry::primitive::{DotShape, PrimitiveShape}, graph::{GenericIndex, GetPetgraphIndex}, diff --git a/src/router/draw.rs b/src/router/draw.rs index 6e305d4..6b3c9ec 100644 --- a/src/router/draw.rs +++ b/src/router/draw.rs @@ -17,9 +17,8 @@ use crate::{ graph::{GetLayer, GetMaybeNet, MakePrimitive}, head::{CaneHead, GetFace, Head}, primitive::GetOtherJoint, - rules::AccessRules, seg::{LoneLooseSegWeight, SeqLooseSegWeight}, - DrawingException, Guide, Infringement, + AccessRules, DrawingException, Guide, Infringement, }, layout::{Layout, LayoutEdit}, math::{Circle, NoTangents}, diff --git a/src/router/navcord.rs b/src/router/navcord.rs index daecc5e..7e66d66 100644 --- a/src/router/navcord.rs +++ b/src/router/navcord.rs @@ -11,7 +11,7 @@ use crate::{ dot::FixedDotIndex, graph::PrimitiveIndex, head::{BareHead, CaneHead, Head}, - rules::AccessRules, + AccessRules, }, layout::{Layout, LayoutEdit}, }; diff --git a/src/router/navcorder.rs b/src/router/navcorder.rs index a5eaeb3..2fd2553 100644 --- a/src/router/navcorder.rs +++ b/src/router/navcorder.rs @@ -6,7 +6,7 @@ use contracts_try::{debug_ensures, debug_requires}; use thiserror::Error; use crate::{ - drawing::{band::BandTermsegIndex, dot::FixedDotIndex, rules::AccessRules}, + drawing::{band::BandTermsegIndex, dot::FixedDotIndex, AccessRules}, layout::{Layout, LayoutEdit}, }; diff --git a/src/router/navmesh.rs b/src/router/navmesh.rs index 357c9f5..784405a 100644 --- a/src/router/navmesh.rs +++ b/src/router/navmesh.rs @@ -25,8 +25,7 @@ use crate::{ gear::{GearIndex, GetNextGear}, graph::{GetLayer, GetMaybeNet, MakePrimitive, PrimitiveIndex}, primitive::{MakePrimitiveShape, Primitive}, - rules::AccessRules, - Drawing, + AccessRules, Drawing, }, geometry::shape::AccessShape, graph::{GetPetgraphIndex, MakeRef}, diff --git a/src/router/route.rs b/src/router/route.rs index de8c05f..f2457c4 100644 --- a/src/router/route.rs +++ b/src/router/route.rs @@ -7,9 +7,7 @@ use std::ops::ControlFlow; use derive_getters::{Dissolve, Getters}; use crate::{ - drawing::{ - band::BandTermsegIndex, dot::FixedDotIndex, graph::PrimitiveIndex, rules::AccessRules, - }, + drawing::{band::BandTermsegIndex, dot::FixedDotIndex, graph::PrimitiveIndex, AccessRules}, geometry::primitive::PrimitiveShape, layout::LayoutEdit, router::{ diff --git a/src/router/router.rs b/src/router/router.rs index 28f8a89..ae34300 100644 --- a/src/router/router.rs +++ b/src/router/router.rs @@ -14,8 +14,7 @@ use crate::{ graph::{MakePrimitive, PrimitiveIndex}, head::GetFace, primitive::MakePrimitiveShape, - rules::AccessRules, - Collision, DrawingException, Guide, Infringement, + AccessRules, Collision, DrawingException, Guide, Infringement, }, geometry::{ primitive::PrimitiveShape, diff --git a/src/specctra/mod.rs b/src/specctra/mod.rs index 9f60f33..107baf1 100644 --- a/src/specctra/mod.rs +++ b/src/specctra/mod.rs @@ -11,4 +11,7 @@ pub use specctra_core::error::{ParseError, ParseErrorContext}; pub use specctra_core::mesadata; use specctra_core::*; +pub trait AccessRules: specctra_core::rules::AccessRules {} +impl AccessRules for T where T: specctra_core::rules::AccessRules {} + pub mod design;