Remove dependency on `enum-as-inner` crate

Fixes https://codeberg.org/mikolaj/topola/issues/13
This commit is contained in:
Mikolaj Wielgus 2023-12-13 14:29:07 +00:00
parent 98ef425ad8
commit f2991af721
5 changed files with 110 additions and 121 deletions

View File

@ -20,9 +20,6 @@ version = "2.2.0"
[dependencies.enum_dispatch] [dependencies.enum_dispatch]
version = "0.3.12" version = "0.3.12"
[dependencies.enum-as-inner]
version = "0.6.0"
[dependencies.itertools] [dependencies.itertools]
version = "0.8.2" version = "0.8.2"

View File

@ -1,4 +1,3 @@
use enum_as_inner::EnumAsInner;
use enum_dispatch::enum_dispatch; use enum_dispatch::enum_dispatch;
use petgraph::stable_graph::{NodeIndex, StableDiGraph}; use petgraph::stable_graph::{NodeIndex, StableDiGraph};
use std::{ use std::{
@ -39,7 +38,7 @@ pub trait GetWidth {
fn width(&self) -> f64; fn width(&self) -> f64;
} }
macro_rules! impl_type { macro_rules! impl_weight {
($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => { ($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => {
impl Retag for $weight_struct { impl Retag for $weight_struct {
fn retag(&self, index: NodeIndex<usize>) -> Index { fn retag(&self, index: NodeIndex<usize>) -> Index {
@ -76,7 +75,7 @@ macro_rules! impl_type {
} }
#[enum_dispatch(Retag, GetNet, GetNetMut)] #[enum_dispatch(Retag, GetNet, GetNetMut)]
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub enum Weight { pub enum Weight {
FixedDot(FixedDotWeight), FixedDot(FixedDotWeight),
LooseDot(LooseDotWeight), LooseDot(LooseDotWeight),
@ -87,7 +86,7 @@ pub enum Weight {
} }
#[enum_dispatch(GetNodeIndex, MakePrimitive)] #[enum_dispatch(GetNodeIndex, MakePrimitive)]
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub enum Index { pub enum Index {
FixedDot(FixedDotIndex), FixedDot(FixedDotIndex),
LooseDot(LooseDotIndex), LooseDot(LooseDotIndex),
@ -98,7 +97,7 @@ pub enum Index {
} }
#[enum_dispatch(GetNodeIndex, MakePrimitive)] #[enum_dispatch(GetNodeIndex, MakePrimitive)]
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub enum DotIndex { pub enum DotIndex {
Fixed(FixedDotIndex), Fixed(FixedDotIndex),
Loose(LooseDotIndex), Loose(LooseDotIndex),
@ -114,7 +113,7 @@ impl From<DotIndex> for Index {
} }
#[enum_dispatch(GetNodeIndex, MakePrimitive)] #[enum_dispatch(GetNodeIndex, MakePrimitive)]
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub enum SegIndex { pub enum SegIndex {
Fixed(FixedSegIndex), Fixed(FixedSegIndex),
Loose(LooseSegIndex), Loose(LooseSegIndex),
@ -130,7 +129,7 @@ impl From<SegIndex> for Index {
} }
#[enum_dispatch(GetNodeIndex, MakePrimitive)] #[enum_dispatch(GetNodeIndex, MakePrimitive)]
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub enum BendIndex { pub enum BendIndex {
Fixed(FixedBendIndex), Fixed(FixedBendIndex),
Loose(LooseBendIndex), Loose(LooseBendIndex),
@ -153,7 +152,7 @@ pub struct FixedDotWeight {
pub circle: Circle, pub circle: Circle,
} }
impl_type!(FixedDotWeight, FixedDot, FixedDotIndex); impl_weight!(FixedDotWeight, FixedDot, FixedDotIndex);
impl DotWeight for FixedDotWeight {} impl DotWeight for FixedDotWeight {}
impl GetWidth for FixedDotWeight { impl GetWidth for FixedDotWeight {
@ -168,7 +167,7 @@ pub struct LooseDotWeight {
pub circle: Circle, pub circle: Circle,
} }
impl_type!(LooseDotWeight, LooseDot, LooseDotIndex); impl_weight!(LooseDotWeight, LooseDot, LooseDotIndex);
impl DotWeight for LooseDotWeight {} impl DotWeight for LooseDotWeight {}
impl GetWidth for LooseDotWeight { impl GetWidth for LooseDotWeight {
@ -185,7 +184,7 @@ pub struct FixedSegWeight {
pub width: f64, pub width: f64,
} }
impl_type!(FixedSegWeight, FixedSeg, FixedSegIndex); impl_weight!(FixedSegWeight, FixedSeg, FixedSegIndex);
impl SegWeight for FixedSegWeight {} impl SegWeight for FixedSegWeight {}
impl GetWidth for FixedSegWeight { impl GetWidth for FixedSegWeight {
@ -199,7 +198,7 @@ pub struct LooseSegWeight {
pub net: i64, pub net: i64,
} }
impl_type!(LooseSegWeight, LooseSeg, LooseSegIndex); impl_weight!(LooseSegWeight, LooseSeg, LooseSegIndex);
impl SegWeight for LooseSegWeight {} impl SegWeight for LooseSegWeight {}
pub trait BendWeight: GetNet + Into<Weight> + Copy {} pub trait BendWeight: GetNet + Into<Weight> + Copy {}
@ -211,7 +210,7 @@ pub struct FixedBendWeight {
pub cw: bool, pub cw: bool,
} }
impl_type!(FixedBendWeight, FixedBend, FixedBendIndex); impl_weight!(FixedBendWeight, FixedBend, FixedBendIndex);
impl BendWeight for FixedBendWeight {} impl BendWeight for FixedBendWeight {}
impl GetWidth for FixedBendWeight { impl GetWidth for FixedBendWeight {
@ -226,10 +225,10 @@ pub struct LooseBendWeight {
pub cw: bool, pub cw: bool,
} }
impl_type!(LooseBendWeight, LooseBend, LooseBendIndex); impl_weight!(LooseBendWeight, LooseBend, LooseBendIndex);
impl BendWeight for LooseBendWeight {} impl BendWeight for LooseBendWeight {}
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub enum Label { pub enum Label {
Adjacent, Adjacent,
Outer, Outer,

View File

@ -38,7 +38,7 @@ impl Layout {
for index in path for index in path
.interior() .interior()
.into_iter() .into_iter()
.filter(|index| !index.is_loose_dot()) .filter(|index| !matches!(index, Index::LooseDot(..)))
{ {
self.remove(index); self.remove(index);
} }
@ -49,7 +49,7 @@ impl Layout {
for index in path for index in path
.interior() .interior()
.into_iter() .into_iter()
.filter(|index| index.is_loose_dot()) .filter(|index| matches!(index, Index::LooseDot(..)))
{ {
self.remove(index); self.remove(index);
} }
@ -270,10 +270,12 @@ impl Layout {
.graph .graph
.neighbors(inner.node_index()) .neighbors(inner.node_index())
.filter(|ni| { .filter(|ni| {
self.graph matches!(
.edge_weight(self.graph.find_edge(inner.node_index(), *ni).unwrap()) self.graph
.unwrap() .edge_weight(self.graph.find_edge(inner.node_index(), *ni).unwrap())
.is_core() .unwrap(),
Label::Core
)
}) })
.map(|ni| FixedDotIndex::new(ni)) .map(|ni| FixedDotIndex::new(ni))
.collect::<Vec<FixedDotIndex>>() .collect::<Vec<FixedDotIndex>>()
@ -324,19 +326,13 @@ impl Layout {
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))] #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count()))]
pub fn flip_bend(&mut self, bend: FixedBendIndex) { pub fn flip_bend(&mut self, bend: FixedBendIndex) {
self.remove_from_rtree(bend.into()); self.remove_from_rtree(bend.into());
let cw = self
.graph let Some(Weight::FixedBend(weight)) = self.graph.node_weight_mut(bend.node_index()) else {
.node_weight(bend.node_index()) unreachable!();
.unwrap() };
.into_fixed_bend()
.unwrap() weight.cw = !weight.cw;
.cw;
self.graph
.node_weight_mut(bend.node_index())
.unwrap()
.as_fixed_bend_mut()
.unwrap()
.cw = !cw;
self.insert_into_rtree(bend.into()); self.insert_into_rtree(bend.into());
} }

View File

@ -62,10 +62,12 @@ pub trait GetFirstLayer: GetGraph + GetNodeIndex {
.neighbors_directed(self.node_index(), Incoming) .neighbors_directed(self.node_index(), Incoming)
.filter(|ni| self.graph().find_edge(self.node_index(), *ni).is_some()) .filter(|ni| self.graph().find_edge(self.node_index(), *ni).is_some())
.filter(|ni| { .filter(|ni| {
self.graph() matches!(
.edge_weight(self.graph().find_edge(self.node_index(), *ni).unwrap()) self.graph()
.unwrap() .edge_weight(self.graph().find_edge(self.node_index(), *ni).unwrap())
.is_core() .unwrap(),
Label::Core
)
}) })
.map(|ni| LooseBendIndex::new(ni)) .map(|ni| LooseBendIndex::new(ni))
.next() .next()
@ -77,10 +79,12 @@ pub trait GetCore: GetGraph + GetNodeIndex {
self.graph() self.graph()
.neighbors(self.node_index()) .neighbors(self.node_index())
.filter(|ni| { .filter(|ni| {
self.graph() matches!(
.edge_weight(self.graph().find_edge(self.node_index(), *ni).unwrap()) self.graph()
.unwrap() .edge_weight(self.graph().find_edge(self.node_index(), *ni).unwrap())
.is_core() .unwrap(),
Label::Core
)
}) })
.map(|ni| FixedDotIndex::new(ni)) .map(|ni| FixedDotIndex::new(ni))
.next() .next()
@ -93,10 +97,12 @@ pub trait GetInnerOuter: GetGraph + GetNodeIndex {
self.graph() self.graph()
.neighbors_directed(self.node_index(), Incoming) .neighbors_directed(self.node_index(), Incoming)
.filter(|ni| { .filter(|ni| {
self.graph() matches!(
.edge_weight(self.graph().find_edge(*ni, self.node_index()).unwrap()) self.graph()
.unwrap() .edge_weight(self.graph().find_edge(*ni, self.node_index()).unwrap())
.is_outer() .unwrap(),
Label::Outer
)
}) })
.map(|ni| LooseBendIndex::new(ni)) .map(|ni| LooseBendIndex::new(ni))
.next() .next()
@ -106,16 +112,32 @@ pub trait GetInnerOuter: GetGraph + GetNodeIndex {
self.graph() self.graph()
.neighbors_directed(self.node_index(), Outgoing) .neighbors_directed(self.node_index(), Outgoing)
.filter(|ni| { .filter(|ni| {
self.graph() matches!(
.edge_weight(self.graph().find_edge(self.node_index(), *ni).unwrap()) self.graph()
.unwrap() .edge_weight(self.graph().find_edge(self.node_index(), *ni).unwrap())
.is_outer() .unwrap(),
Label::Outer
)
}) })
.map(|ni| LooseBendIndex::new(ni)) .map(|ni| LooseBendIndex::new(ni))
.next() .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)] #[enum_dispatch(GetNet, GetWidth, GetGraph, GetConnectable, MakeShape)]
pub enum Primitive<'a> { pub enum Primitive<'a> {
FixedDot(FixedDot<'a>), FixedDot(FixedDot<'a>),
@ -145,15 +167,17 @@ impl<'a, W> GenericPrimitive<'a, W> {
self.graph self.graph
.neighbors_undirected(self.index.node_index()) .neighbors_undirected(self.index.node_index())
.filter(|ni| { .filter(|ni| {
self.graph matches!(
.edge_weight( self.graph
self.graph .edge_weight(
.find_edge_undirected(self.index.node_index(), *ni) self.graph
.unwrap() .find_edge_undirected(self.index.node_index(), *ni)
.0, .unwrap()
) .0,
.unwrap() )
.is_adjacent() .unwrap(),
Label::Adjacent
)
}) })
.collect() .collect()
} }
@ -205,12 +229,7 @@ where
} }
pub type FixedDot<'a> = GenericPrimitive<'a, FixedDotWeight>; pub type FixedDot<'a> = GenericPrimitive<'a, FixedDotWeight>;
impl_primitive!(FixedDot, FixedDotWeight);
impl<'a> GetWeight<FixedDotWeight> for FixedDot<'a> {
fn weight(&self) -> FixedDotWeight {
self.tagged_weight().into_fixed_dot().unwrap()
}
}
impl<'a> MakeShape for FixedDot<'a> { impl<'a> MakeShape for FixedDot<'a> {
fn shape(&self) -> Shape { fn shape(&self) -> Shape {
@ -224,23 +243,26 @@ impl<'a> TraverseOutward for FixedDot<'a> {}
impl<'a> GetFirstLayer for FixedDot<'a> {} impl<'a> GetFirstLayer for FixedDot<'a> {}
pub type LooseDot<'a> = GenericPrimitive<'a, LooseDotWeight>; pub type LooseDot<'a> = GenericPrimitive<'a, LooseDotWeight>;
impl_primitive!(LooseDot, LooseDotWeight);
impl<'a> LooseDot<'a> { impl<'a> LooseDot<'a> {
pub fn seg(&self) -> Option<LooseSegIndex> { pub fn seg(&self) -> Option<LooseSegIndex> {
self.graph self.graph
.neighbors_undirected(self.index.node_index()) .neighbors_undirected(self.index.node_index())
.filter(|ni| { .filter(|ni| {
self.graph matches!(
.edge_weight( self.graph
self.graph .edge_weight(
.find_edge_undirected(self.index.node_index(), *ni) self.graph
.unwrap() .find_edge_undirected(self.index.node_index(), *ni)
.0, .unwrap()
) .0,
.unwrap() )
.is_adjacent() .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)) .map(|ni| LooseSegIndex::new(ni))
.next() .next()
} }
@ -249,29 +271,25 @@ impl<'a> LooseDot<'a> {
self.graph self.graph
.neighbors_undirected(self.index.node_index()) .neighbors_undirected(self.index.node_index())
.filter(|ni| { .filter(|ni| {
self.graph matches!(
.edge_weight( self.graph
self.graph .edge_weight(
.find_edge_undirected(self.index.node_index(), *ni) self.graph
.unwrap() .find_edge_undirected(self.index.node_index(), *ni)
.0, .unwrap()
) .0,
.unwrap() )
.is_adjacent() .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)) .map(|ni| LooseBendIndex::new(ni))
.next() .next()
.unwrap() .unwrap()
} }
} }
impl<'a> GetWeight<LooseDotWeight> for LooseDot<'a> {
fn weight(&self) -> LooseDotWeight {
self.tagged_weight().into_loose_dot().unwrap()
}
}
impl<'a> MakeShape for LooseDot<'a> { impl<'a> MakeShape for LooseDot<'a> {
fn shape(&self) -> Shape { fn shape(&self) -> Shape {
Shape::Dot(DotShape { Shape::Dot(DotShape {
@ -281,12 +299,7 @@ impl<'a> MakeShape for LooseDot<'a> {
} }
pub type FixedSeg<'a> = GenericPrimitive<'a, FixedSegWeight>; pub type FixedSeg<'a> = GenericPrimitive<'a, FixedSegWeight>;
impl_primitive!(FixedSeg, FixedSegWeight);
impl<'a> GetWeight<FixedSegWeight> for FixedSeg<'a> {
fn weight(&self) -> FixedSegWeight {
self.tagged_weight().into_fixed_seg().unwrap()
}
}
impl<'a> MakeShape for FixedSeg<'a> { impl<'a> MakeShape for FixedSeg<'a> {
fn shape(&self) -> Shape { fn shape(&self) -> Shape {
@ -309,12 +322,7 @@ impl<'a> GetEnds<FixedDotIndex, FixedDotIndex> for FixedSeg<'a> {
impl<'a> GetOtherEnd<FixedDotIndex, FixedDotIndex> for FixedSeg<'a> {} impl<'a> GetOtherEnd<FixedDotIndex, FixedDotIndex> for FixedSeg<'a> {}
pub type LooseSeg<'a> = GenericPrimitive<'a, LooseSegWeight>; pub type LooseSeg<'a> = GenericPrimitive<'a, LooseSegWeight>;
impl_primitive!(LooseSeg, LooseSegWeight);
impl<'a> GetWeight<LooseSegWeight> for LooseSeg<'a> {
fn weight(&self) -> LooseSegWeight {
self.tagged_weight().into_loose_seg().unwrap()
}
}
impl<'a> MakeShape for LooseSeg<'a> { impl<'a> MakeShape for LooseSeg<'a> {
fn shape(&self) -> Shape { fn shape(&self) -> Shape {
@ -339,9 +347,9 @@ impl<'a> GetWidth for LooseSeg<'a> {
impl<'a> GetEnds<DotIndex, LooseDotIndex> for LooseSeg<'a> { impl<'a> GetEnds<DotIndex, LooseDotIndex> for LooseSeg<'a> {
fn ends(&self) -> (DotIndex, LooseDotIndex) { fn ends(&self) -> (DotIndex, LooseDotIndex) {
let v = self.adjacents(); 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])) (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])) (FixedDotIndex::new(v[1]).into(), LooseDotIndex::new(v[0]))
} else { } else {
(LooseDotIndex::new(v[0]).into(), LooseDotIndex::new(v[1])) (LooseDotIndex::new(v[0]).into(), LooseDotIndex::new(v[1]))
@ -352,6 +360,7 @@ impl<'a> GetEnds<DotIndex, LooseDotIndex> for LooseSeg<'a> {
impl<'a> GetOtherEnd<DotIndex, LooseDotIndex> for LooseSeg<'a> {} impl<'a> GetOtherEnd<DotIndex, LooseDotIndex> for LooseSeg<'a> {}
pub type FixedBend<'a> = GenericPrimitive<'a, FixedBendWeight>; pub type FixedBend<'a> = GenericPrimitive<'a, FixedBendWeight>;
impl_primitive!(FixedBend, FixedBendWeight);
impl<'a> FixedBend<'a> { impl<'a> FixedBend<'a> {
fn inner_radius(&self) -> f64 { fn inner_radius(&self) -> f64 {
@ -367,12 +376,6 @@ impl<'a> FixedBend<'a> {
} }
} }
impl<'a> GetWeight<FixedBendWeight> for FixedBend<'a> {
fn weight(&self) -> FixedBendWeight {
self.tagged_weight().into_fixed_bend().unwrap()
}
}
impl<'a> MakeShape for FixedBend<'a> { impl<'a> MakeShape for FixedBend<'a> {
fn shape(&self) -> Shape { fn shape(&self) -> Shape {
let ends = self.ends(); 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> {} //impl<'a> GetInnerOuter for FixedBend<'a> {}
pub type LooseBend<'a> = GenericPrimitive<'a, LooseBendWeight>; pub type LooseBend<'a> = GenericPrimitive<'a, LooseBendWeight>;
impl_primitive!(LooseBend, LooseBendWeight);
impl<'a> LooseBend<'a> { impl<'a> LooseBend<'a> {
fn inner_radius(&self) -> f64 { fn inner_radius(&self) -> f64 {
@ -431,12 +435,6 @@ impl<'a> LooseBend<'a> {
} }
} }
impl<'a> GetWeight<LooseBendWeight> for LooseBend<'a> {
fn weight(&self) -> LooseBendWeight {
self.tagged_weight().into_loose_bend().unwrap()
}
}
impl<'a> MakeShape for LooseBend<'a> { impl<'a> MakeShape for LooseBend<'a> {
fn shape(&self) -> Shape { fn shape(&self) -> Shape {
let ends = self.ends(); let ends = self.ends();

View File

@ -1,4 +1,3 @@
use enum_as_inner::EnumAsInner;
use enum_dispatch::enum_dispatch; use enum_dispatch::enum_dispatch;
use geo::{point, polygon, EuclideanDistance, Intersects, Point, Polygon, Rotate}; use geo::{point, polygon, EuclideanDistance, Intersects, Point, Polygon, Rotate};
use rstar::{RTreeObject, AABB}; use rstar::{RTreeObject, AABB};
@ -15,7 +14,7 @@ pub trait ShapeTrait {
} }
#[enum_dispatch(ShapeTrait)] #[enum_dispatch(ShapeTrait)]
#[derive(Debug, Clone, Copy, EnumAsInner, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub enum Shape { pub enum Shape {
// Intentionally in different order to reorder `self.intersects(...)` properly. // Intentionally in different order to reorder `self.intersects(...)` properly.
Dot(DotShape), Dot(DotShape),