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]
version = "0.3.12"
[dependencies.enum-as-inner]
version = "0.6.0"
[dependencies.itertools]
version = "0.8.2"

View File

@ -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<usize>) -> 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<DotIndex> 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<SegIndex> 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<Weight> + 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,

View File

@ -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::<Vec<FixedDotIndex>>()
@ -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());
}

View File

@ -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<FixedDotWeight> 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<LooseSegIndex> {
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<LooseDotWeight> 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<FixedSegWeight> 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<FixedDotIndex, FixedDotIndex> for FixedSeg<'a> {
impl<'a> GetOtherEnd<FixedDotIndex, FixedDotIndex> for FixedSeg<'a> {}
pub type LooseSeg<'a> = GenericPrimitive<'a, LooseSegWeight>;
impl<'a> GetWeight<LooseSegWeight> 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<DotIndex, LooseDotIndex> 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<DotIndex, LooseDotIndex> for LooseSeg<'a> {
impl<'a> GetOtherEnd<DotIndex, LooseDotIndex> 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<FixedBendWeight> 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<LooseBendWeight> 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();

View File

@ -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),