From f2991af721410c2e52e89a76105f6c44c115a666 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Wed, 13 Dec 2023 14:29:07 +0000 Subject: [PATCH] Remove dependency on `enum-as-inner` crate Fixes https://codeberg.org/mikolaj/topola/issues/13 --- Cargo.toml | 3 - src/graph.rs | 27 ++++---- src/layout.rs | 34 +++++----- src/primitive.rs | 164 +++++++++++++++++++++++------------------------ src/shape.rs | 3 +- 5 files changed, 110 insertions(+), 121 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2643d90..1486f3f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,9 +20,6 @@ version = "2.2.0" [dependencies.enum_dispatch] version = "0.3.12" -[dependencies.enum-as-inner] -version = "0.6.0" - [dependencies.itertools] version = "0.8.2" diff --git a/src/graph.rs b/src/graph.rs index 20cc674..b77e70a 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -1,4 +1,3 @@ -use enum_as_inner::EnumAsInner; use enum_dispatch::enum_dispatch; use petgraph::stable_graph::{NodeIndex, StableDiGraph}; use std::{ @@ -39,7 +38,7 @@ pub trait GetWidth { fn width(&self) -> f64; } -macro_rules! impl_type { +macro_rules! impl_weight { ($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => { impl Retag for $weight_struct { fn retag(&self, index: NodeIndex) -> Index { @@ -76,7 +75,7 @@ macro_rules! impl_type { } #[enum_dispatch(Retag, GetNet, GetNetMut)] -#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq)] pub enum Weight { FixedDot(FixedDotWeight), LooseDot(LooseDotWeight), @@ -87,7 +86,7 @@ pub enum Weight { } #[enum_dispatch(GetNodeIndex, MakePrimitive)] -#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq)] pub enum Index { FixedDot(FixedDotIndex), LooseDot(LooseDotIndex), @@ -98,7 +97,7 @@ pub enum Index { } #[enum_dispatch(GetNodeIndex, MakePrimitive)] -#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq)] pub enum DotIndex { Fixed(FixedDotIndex), Loose(LooseDotIndex), @@ -114,7 +113,7 @@ impl From for Index { } #[enum_dispatch(GetNodeIndex, MakePrimitive)] -#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq)] pub enum SegIndex { Fixed(FixedSegIndex), Loose(LooseSegIndex), @@ -130,7 +129,7 @@ impl From for Index { } #[enum_dispatch(GetNodeIndex, MakePrimitive)] -#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq)] pub enum BendIndex { Fixed(FixedBendIndex), Loose(LooseBendIndex), @@ -153,7 +152,7 @@ pub struct FixedDotWeight { pub circle: Circle, } -impl_type!(FixedDotWeight, FixedDot, FixedDotIndex); +impl_weight!(FixedDotWeight, FixedDot, FixedDotIndex); impl DotWeight for FixedDotWeight {} impl GetWidth for FixedDotWeight { @@ -168,7 +167,7 @@ pub struct LooseDotWeight { pub circle: Circle, } -impl_type!(LooseDotWeight, LooseDot, LooseDotIndex); +impl_weight!(LooseDotWeight, LooseDot, LooseDotIndex); impl DotWeight for LooseDotWeight {} impl GetWidth for LooseDotWeight { @@ -185,7 +184,7 @@ pub struct FixedSegWeight { pub width: f64, } -impl_type!(FixedSegWeight, FixedSeg, FixedSegIndex); +impl_weight!(FixedSegWeight, FixedSeg, FixedSegIndex); impl SegWeight for FixedSegWeight {} impl GetWidth for FixedSegWeight { @@ -199,7 +198,7 @@ pub struct LooseSegWeight { pub net: i64, } -impl_type!(LooseSegWeight, LooseSeg, LooseSegIndex); +impl_weight!(LooseSegWeight, LooseSeg, LooseSegIndex); impl SegWeight for LooseSegWeight {} pub trait BendWeight: GetNet + Into + Copy {} @@ -211,7 +210,7 @@ pub struct FixedBendWeight { pub cw: bool, } -impl_type!(FixedBendWeight, FixedBend, FixedBendIndex); +impl_weight!(FixedBendWeight, FixedBend, FixedBendIndex); impl BendWeight for FixedBendWeight {} impl GetWidth for FixedBendWeight { @@ -226,10 +225,10 @@ pub struct LooseBendWeight { pub cw: bool, } -impl_type!(LooseBendWeight, LooseBend, LooseBendIndex); +impl_weight!(LooseBendWeight, LooseBend, LooseBendIndex); impl BendWeight for LooseBendWeight {} -#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq)] pub enum Label { Adjacent, Outer, diff --git a/src/layout.rs b/src/layout.rs index ce102a3..2002ffe 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -38,7 +38,7 @@ impl Layout { for index in path .interior() .into_iter() - .filter(|index| !index.is_loose_dot()) + .filter(|index| !matches!(index, Index::LooseDot(..))) { self.remove(index); } @@ -49,7 +49,7 @@ impl Layout { for index in path .interior() .into_iter() - .filter(|index| index.is_loose_dot()) + .filter(|index| matches!(index, Index::LooseDot(..))) { self.remove(index); } @@ -270,10 +270,12 @@ impl Layout { .graph .neighbors(inner.node_index()) .filter(|ni| { - self.graph - .edge_weight(self.graph.find_edge(inner.node_index(), *ni).unwrap()) - .unwrap() - .is_core() + matches!( + self.graph + .edge_weight(self.graph.find_edge(inner.node_index(), *ni).unwrap()) + .unwrap(), + Label::Core + ) }) .map(|ni| FixedDotIndex::new(ni)) .collect::>() @@ -324,19 +326,13 @@ impl Layout { #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))] pub fn flip_bend(&mut self, bend: FixedBendIndex) { self.remove_from_rtree(bend.into()); - let cw = self - .graph - .node_weight(bend.node_index()) - .unwrap() - .into_fixed_bend() - .unwrap() - .cw; - self.graph - .node_weight_mut(bend.node_index()) - .unwrap() - .as_fixed_bend_mut() - .unwrap() - .cw = !cw; + + let Some(Weight::FixedBend(weight)) = self.graph.node_weight_mut(bend.node_index()) else { + unreachable!(); + }; + + weight.cw = !weight.cw; + self.insert_into_rtree(bend.into()); } diff --git a/src/primitive.rs b/src/primitive.rs index 4eda070..884a71b 100644 --- a/src/primitive.rs +++ b/src/primitive.rs @@ -62,10 +62,12 @@ pub trait GetFirstLayer: GetGraph + GetNodeIndex { .neighbors_directed(self.node_index(), Incoming) .filter(|ni| self.graph().find_edge(self.node_index(), *ni).is_some()) .filter(|ni| { - self.graph() - .edge_weight(self.graph().find_edge(self.node_index(), *ni).unwrap()) - .unwrap() - .is_core() + matches!( + self.graph() + .edge_weight(self.graph().find_edge(self.node_index(), *ni).unwrap()) + .unwrap(), + Label::Core + ) }) .map(|ni| LooseBendIndex::new(ni)) .next() @@ -77,10 +79,12 @@ pub trait GetCore: GetGraph + GetNodeIndex { self.graph() .neighbors(self.node_index()) .filter(|ni| { - self.graph() - .edge_weight(self.graph().find_edge(self.node_index(), *ni).unwrap()) - .unwrap() - .is_core() + matches!( + self.graph() + .edge_weight(self.graph().find_edge(self.node_index(), *ni).unwrap()) + .unwrap(), + Label::Core + ) }) .map(|ni| FixedDotIndex::new(ni)) .next() @@ -93,10 +97,12 @@ pub trait GetInnerOuter: GetGraph + GetNodeIndex { self.graph() .neighbors_directed(self.node_index(), Incoming) .filter(|ni| { - self.graph() - .edge_weight(self.graph().find_edge(*ni, self.node_index()).unwrap()) - .unwrap() - .is_outer() + matches!( + self.graph() + .edge_weight(self.graph().find_edge(*ni, self.node_index()).unwrap()) + .unwrap(), + Label::Outer + ) }) .map(|ni| LooseBendIndex::new(ni)) .next() @@ -106,16 +112,32 @@ pub trait GetInnerOuter: GetGraph + GetNodeIndex { self.graph() .neighbors_directed(self.node_index(), Outgoing) .filter(|ni| { - self.graph() - .edge_weight(self.graph().find_edge(self.node_index(), *ni).unwrap()) - .unwrap() - .is_outer() + matches!( + self.graph() + .edge_weight(self.graph().find_edge(self.node_index(), *ni).unwrap()) + .unwrap(), + Label::Outer + ) }) .map(|ni| LooseBendIndex::new(ni)) .next() } } +macro_rules! impl_primitive { + ($primitive_struct:ident, $weight_struct:ident) => { + impl<'a> GetWeight<$weight_struct> for $primitive_struct<'a> { + fn weight(&self) -> $weight_struct { + if let Weight::$primitive_struct(weight) = self.tagged_weight() { + weight + } else { + unreachable!() + } + } + } + }; +} + #[enum_dispatch(GetNet, GetWidth, GetGraph, GetConnectable, MakeShape)] pub enum Primitive<'a> { FixedDot(FixedDot<'a>), @@ -145,15 +167,17 @@ impl<'a, W> GenericPrimitive<'a, W> { self.graph .neighbors_undirected(self.index.node_index()) .filter(|ni| { - self.graph - .edge_weight( - self.graph - .find_edge_undirected(self.index.node_index(), *ni) - .unwrap() - .0, - ) - .unwrap() - .is_adjacent() + matches!( + self.graph + .edge_weight( + self.graph + .find_edge_undirected(self.index.node_index(), *ni) + .unwrap() + .0, + ) + .unwrap(), + Label::Adjacent + ) }) .collect() } @@ -205,12 +229,7 @@ where } pub type FixedDot<'a> = GenericPrimitive<'a, FixedDotWeight>; - -impl<'a> GetWeight for FixedDot<'a> { - fn weight(&self) -> FixedDotWeight { - self.tagged_weight().into_fixed_dot().unwrap() - } -} +impl_primitive!(FixedDot, FixedDotWeight); impl<'a> MakeShape for FixedDot<'a> { fn shape(&self) -> Shape { @@ -224,23 +243,26 @@ impl<'a> TraverseOutward for FixedDot<'a> {} impl<'a> GetFirstLayer for FixedDot<'a> {} pub type LooseDot<'a> = GenericPrimitive<'a, LooseDotWeight>; +impl_primitive!(LooseDot, LooseDotWeight); impl<'a> LooseDot<'a> { pub fn seg(&self) -> Option { self.graph .neighbors_undirected(self.index.node_index()) .filter(|ni| { - self.graph - .edge_weight( - self.graph - .find_edge_undirected(self.index.node_index(), *ni) - .unwrap() - .0, - ) - .unwrap() - .is_adjacent() + matches!( + self.graph + .edge_weight( + self.graph + .find_edge_undirected(self.index.node_index(), *ni) + .unwrap() + .0, + ) + .unwrap(), + Label::Adjacent + ) }) - .filter(|ni| self.graph.node_weight(*ni).unwrap().is_loose_seg()) + .filter(|ni| matches!(self.graph.node_weight(*ni).unwrap(), Weight::LooseSeg(..))) .map(|ni| LooseSegIndex::new(ni)) .next() } @@ -249,29 +271,25 @@ impl<'a> LooseDot<'a> { self.graph .neighbors_undirected(self.index.node_index()) .filter(|ni| { - self.graph - .edge_weight( - self.graph - .find_edge_undirected(self.index.node_index(), *ni) - .unwrap() - .0, - ) - .unwrap() - .is_adjacent() + matches!( + self.graph + .edge_weight( + self.graph + .find_edge_undirected(self.index.node_index(), *ni) + .unwrap() + .0, + ) + .unwrap(), + Label::Adjacent + ) }) - .filter(|ni| self.graph.node_weight(*ni).unwrap().is_loose_bend()) + .filter(|ni| matches!(self.graph.node_weight(*ni).unwrap(), Weight::LooseBend(..))) .map(|ni| LooseBendIndex::new(ni)) .next() .unwrap() } } -impl<'a> GetWeight for LooseDot<'a> { - fn weight(&self) -> LooseDotWeight { - self.tagged_weight().into_loose_dot().unwrap() - } -} - impl<'a> MakeShape for LooseDot<'a> { fn shape(&self) -> Shape { Shape::Dot(DotShape { @@ -281,12 +299,7 @@ impl<'a> MakeShape for LooseDot<'a> { } pub type FixedSeg<'a> = GenericPrimitive<'a, FixedSegWeight>; - -impl<'a> GetWeight for FixedSeg<'a> { - fn weight(&self) -> FixedSegWeight { - self.tagged_weight().into_fixed_seg().unwrap() - } -} +impl_primitive!(FixedSeg, FixedSegWeight); impl<'a> MakeShape for FixedSeg<'a> { fn shape(&self) -> Shape { @@ -309,12 +322,7 @@ impl<'a> GetEnds for FixedSeg<'a> { impl<'a> GetOtherEnd for FixedSeg<'a> {} pub type LooseSeg<'a> = GenericPrimitive<'a, LooseSegWeight>; - -impl<'a> GetWeight for LooseSeg<'a> { - fn weight(&self) -> LooseSegWeight { - self.tagged_weight().into_loose_seg().unwrap() - } -} +impl_primitive!(LooseSeg, LooseSegWeight); impl<'a> MakeShape for LooseSeg<'a> { fn shape(&self) -> Shape { @@ -339,9 +347,9 @@ impl<'a> GetWidth for LooseSeg<'a> { impl<'a> GetEnds for LooseSeg<'a> { fn ends(&self) -> (DotIndex, LooseDotIndex) { let v = self.adjacents(); - if self.graph.node_weight(v[0]).unwrap().is_fixed_dot() { + if let Weight::FixedDot(..) = self.graph.node_weight(v[0]).unwrap() { (FixedDotIndex::new(v[0]).into(), LooseDotIndex::new(v[1])) - } else if self.graph.node_weight(v[1]).unwrap().is_fixed_dot() { + } else if let Weight::FixedDot(..) = self.graph.node_weight(v[1]).unwrap() { (FixedDotIndex::new(v[1]).into(), LooseDotIndex::new(v[0])) } else { (LooseDotIndex::new(v[0]).into(), LooseDotIndex::new(v[1])) @@ -352,6 +360,7 @@ impl<'a> GetEnds for LooseSeg<'a> { impl<'a> GetOtherEnd for LooseSeg<'a> {} pub type FixedBend<'a> = GenericPrimitive<'a, FixedBendWeight>; +impl_primitive!(FixedBend, FixedBendWeight); impl<'a> FixedBend<'a> { fn inner_radius(&self) -> f64 { @@ -367,12 +376,6 @@ impl<'a> FixedBend<'a> { } } -impl<'a> GetWeight for FixedBend<'a> { - fn weight(&self) -> FixedBendWeight { - self.tagged_weight().into_fixed_bend().unwrap() - } -} - impl<'a> MakeShape for FixedBend<'a> { fn shape(&self) -> Shape { let ends = self.ends(); @@ -408,6 +411,7 @@ impl<'a> GetCore for FixedBend<'a> {} // TODO: Fixed bends don't have cores actu //impl<'a> GetInnerOuter for FixedBend<'a> {} pub type LooseBend<'a> = GenericPrimitive<'a, LooseBendWeight>; +impl_primitive!(LooseBend, LooseBendWeight); impl<'a> LooseBend<'a> { fn inner_radius(&self) -> f64 { @@ -431,12 +435,6 @@ impl<'a> LooseBend<'a> { } } -impl<'a> GetWeight for LooseBend<'a> { - fn weight(&self) -> LooseBendWeight { - self.tagged_weight().into_loose_bend().unwrap() - } -} - impl<'a> MakeShape for LooseBend<'a> { fn shape(&self) -> Shape { let ends = self.ends(); diff --git a/src/shape.rs b/src/shape.rs index 9dae8a0..5a25aec 100644 --- a/src/shape.rs +++ b/src/shape.rs @@ -1,4 +1,3 @@ -use enum_as_inner::EnumAsInner; use enum_dispatch::enum_dispatch; use geo::{point, polygon, EuclideanDistance, Intersects, Point, Polygon, Rotate}; use rstar::{RTreeObject, AABB}; @@ -15,7 +14,7 @@ pub trait ShapeTrait { } #[enum_dispatch(ShapeTrait)] -#[derive(Debug, Clone, Copy, EnumAsInner, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq)] pub enum Shape { // Intentionally in different order to reorder `self.intersects(...)` properly. Dot(DotShape),