From 4549de098c253af1994a60749d0afdbadf66d7dd Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Fri, 20 Oct 2023 23:44:20 +0000 Subject: [PATCH] primitive: Move `tagged_{prev,next}` to a trait First step towards getting rid of the `untag` macro. --- src/band.rs | 14 ++++---------- src/bow.rs | 2 +- src/graph.rs | 34 +++++++++++++++++++++++++++++++--- src/layout.rs | 2 +- src/primitive.rs | 30 +++++++++++++++++++----------- src/segbend.rs | 2 +- 6 files changed, 57 insertions(+), 27 deletions(-) diff --git a/src/band.rs b/src/band.rs index 5716d68..b6dc0ad 100644 --- a/src/band.rs +++ b/src/band.rs @@ -1,8 +1,8 @@ use petgraph::stable_graph::StableDiGraph; use crate::{ - graph::{DotIndex, Ends, Index, Interior, Label, Weight}, - primitive::GenericPrimitive, + graph::{DotIndex, Ends, Index, Interior, Label, MakePrimitive, Weight}, + primitive::TaggedPrevTaggedNext, }; pub struct Band { @@ -19,10 +19,7 @@ impl Band { let mut next_index = Index::Dot(dot); let mut interior = vec![]; - while let Some(index) = untag!( - next_index, - GenericPrimitive::new(next_index, graph).tagged_prev() - ) { + while let Some(index) = next_index.primitive(graph).tagged_prev() { interior.push(index); next_index = index; } @@ -45,10 +42,7 @@ impl Band { let mut prev_index = Index::Dot(dot); let mut interior = vec![]; - while let Some(index) = untag!( - prev_index, - GenericPrimitive::new(prev_index, graph).tagged_next() - ) { + while let Some(index) = prev_index.primitive(graph).tagged_next() { interior.push(index); prev_index = index; } diff --git a/src/bow.rs b/src/bow.rs index 4ad5ee2..eb8f92f 100644 --- a/src/bow.rs +++ b/src/bow.rs @@ -1,7 +1,7 @@ use petgraph::stable_graph::StableDiGraph; use crate::graph::{BendIndex, DotIndex, Ends, Index, Interior, Label, SegIndex, Weight}; -use crate::primitive::{Bend, Dot, Seg}; +use crate::primitive::{Bend, Dot, Seg, TaggedPrevTaggedNext}; #[derive(Debug, Clone, Copy)] pub struct Bow { diff --git a/src/graph.rs b/src/graph.rs index abe8fa9..2045804 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -1,9 +1,12 @@ use enum_as_inner::EnumAsInner; use enum_dispatch::enum_dispatch; -use petgraph::stable_graph::NodeIndex; +use petgraph::stable_graph::{NodeIndex, StableDiGraph}; use std::marker::PhantomData; -use crate::math::Circle; +use crate::{ + math::Circle, + primitive::{GenericPrimitive, Primitive}, +}; pub trait Interior { fn interior(&self) -> Vec; @@ -83,7 +86,12 @@ pub trait GetNodeIndex { fn node_index(&self) -> NodeIndex; } -#[enum_dispatch(GetNodeIndex)] +#[enum_dispatch] +pub trait MakePrimitive { + fn primitive<'a>(&self, graph: &'a StableDiGraph) -> Primitive<'a>; +} + +#[enum_dispatch(GetNodeIndex, MakePrimitive)] #[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] pub enum Index { Dot(DotIndex), @@ -123,5 +131,25 @@ macro_rules! untag { } pub type DotIndex = GenericIndex; + +impl MakePrimitive for DotIndex { + fn primitive<'a>(&self, graph: &'a StableDiGraph) -> Primitive<'a> { + Primitive::Dot(GenericPrimitive::new(*self, graph)) + } +} + pub type SegIndex = GenericIndex; + +impl MakePrimitive for SegIndex { + fn primitive<'a>(&self, graph: &'a StableDiGraph) -> Primitive<'a> { + Primitive::Seg(GenericPrimitive::new(*self, graph)) + } +} + pub type BendIndex = GenericIndex; + +impl MakePrimitive for BendIndex { + fn primitive<'a>(&self, graph: &'a StableDiGraph) -> Primitive<'a> { + Primitive::Bend(GenericPrimitive::new(*self, graph)) + } +} diff --git a/src/layout.rs b/src/layout.rs index 6556c09..e4f4022 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -12,7 +12,7 @@ use crate::graph::{ BendIndex, BendWeight, DotIndex, DotWeight, GenericIndex, GetNodeIndex, Index, Interior, Label, Retag, SegIndex, SegWeight, Weight, }; -use crate::primitive::{GenericPrimitive, GetWeight, MakeShape}; +use crate::primitive::{GenericPrimitive, GetWeight, MakeShape, TaggedPrevTaggedNext}; use crate::segbend::Segbend; use crate::shape::{Shape, ShapeTrait}; diff --git a/src/primitive.rs b/src/primitive.rs index ce1586e..05166b4 100644 --- a/src/primitive.rs +++ b/src/primitive.rs @@ -11,6 +11,12 @@ use crate::graph::{ use crate::math::{self, Circle}; use crate::shape::{BendShape, DotShape, SegShape, Shape, ShapeTrait}; +#[enum_dispatch] +pub trait TaggedPrevTaggedNext { + fn tagged_prev(&self) -> Option; + fn tagged_next(&self) -> Option; +} + #[enum_dispatch] pub trait GetWeight { fn weight(&self) -> W; @@ -21,7 +27,7 @@ pub trait MakeShape { fn shape(&self) -> Shape; } -#[enum_dispatch(MakeShape)] +#[enum_dispatch(MakeShape, TaggedPrevTaggedNext)] pub enum Primitive<'a> { Dot(Dot<'a>), Seg(Seg<'a>), @@ -74,11 +80,6 @@ impl<'a, W> GenericPrimitive<'a, W> { None } - pub fn tagged_prev(&self) -> Option { - self.prev_node() - .map(|ni| self.graph.node_weight(ni).unwrap().retag(ni)) - } - fn prev_node(&self) -> Option> { self.graph .neighbors_directed(self.index.node_index(), Incoming) @@ -120,11 +121,6 @@ impl<'a, W> GenericPrimitive<'a, W> { None } - pub fn tagged_next(&self) -> Option { - self.next_node() - .map(|ni| self.graph.node_weight(ni).unwrap().retag(ni)) - } - fn next_node(&self) -> Option> { self.graph .neighbors_directed(self.index.node_index(), Outgoing) @@ -218,6 +214,18 @@ impl<'a, W> Ends for GenericPrimitive<'a, W> { } } +impl<'a, W> TaggedPrevTaggedNext for GenericPrimitive<'a, W> { + fn tagged_prev(&self) -> Option { + self.prev_node() + .map(|ni| self.graph.node_weight(ni).unwrap().retag(ni)) + } + + fn tagged_next(&self) -> Option { + self.next_node() + .map(|ni| self.graph.node_weight(ni).unwrap().retag(ni)) + } +} + pub type Dot<'a> = GenericPrimitive<'a, DotWeight>; impl<'a> Dot<'a> { diff --git a/src/segbend.rs b/src/segbend.rs index eafb3a1..1ddf35b 100644 --- a/src/segbend.rs +++ b/src/segbend.rs @@ -2,7 +2,7 @@ use petgraph::stable_graph::StableDiGraph; use crate::{ graph::{BendIndex, DotIndex, Ends, Index, Interior, Label, SegIndex, Weight}, - primitive::{Bend, Dot}, + primitive::{Bend, Dot, TaggedPrevTaggedNext}, }; #[derive(Debug, Clone, Copy)]