primitive: Move `tagged_{prev,next}` to a trait

First step towards getting rid of the `untag` macro.
This commit is contained in:
Mikolaj Wielgus 2023-10-20 23:44:20 +00:00
parent 4d20362e00
commit 4549de098c
6 changed files with 57 additions and 27 deletions

View File

@ -1,8 +1,8 @@
use petgraph::stable_graph::StableDiGraph; use petgraph::stable_graph::StableDiGraph;
use crate::{ use crate::{
graph::{DotIndex, Ends, Index, Interior, Label, Weight}, graph::{DotIndex, Ends, Index, Interior, Label, MakePrimitive, Weight},
primitive::GenericPrimitive, primitive::TaggedPrevTaggedNext,
}; };
pub struct Band { pub struct Band {
@ -19,10 +19,7 @@ impl Band {
let mut next_index = Index::Dot(dot); let mut next_index = Index::Dot(dot);
let mut interior = vec![]; let mut interior = vec![];
while let Some(index) = untag!( while let Some(index) = next_index.primitive(graph).tagged_prev() {
next_index,
GenericPrimitive::new(next_index, graph).tagged_prev()
) {
interior.push(index); interior.push(index);
next_index = index; next_index = index;
} }
@ -45,10 +42,7 @@ impl Band {
let mut prev_index = Index::Dot(dot); let mut prev_index = Index::Dot(dot);
let mut interior = vec![]; let mut interior = vec![];
while let Some(index) = untag!( while let Some(index) = prev_index.primitive(graph).tagged_next() {
prev_index,
GenericPrimitive::new(prev_index, graph).tagged_next()
) {
interior.push(index); interior.push(index);
prev_index = index; prev_index = index;
} }

View File

@ -1,7 +1,7 @@
use petgraph::stable_graph::StableDiGraph; use petgraph::stable_graph::StableDiGraph;
use crate::graph::{BendIndex, DotIndex, Ends, Index, Interior, Label, SegIndex, Weight}; 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)] #[derive(Debug, Clone, Copy)]
pub struct Bow { pub struct Bow {

View File

@ -1,9 +1,12 @@
use enum_as_inner::EnumAsInner; use enum_as_inner::EnumAsInner;
use enum_dispatch::enum_dispatch; use enum_dispatch::enum_dispatch;
use petgraph::stable_graph::NodeIndex; use petgraph::stable_graph::{NodeIndex, StableDiGraph};
use std::marker::PhantomData; use std::marker::PhantomData;
use crate::math::Circle; use crate::{
math::Circle,
primitive::{GenericPrimitive, Primitive},
};
pub trait Interior<T> { pub trait Interior<T> {
fn interior(&self) -> Vec<T>; fn interior(&self) -> Vec<T>;
@ -83,7 +86,12 @@ pub trait GetNodeIndex {
fn node_index(&self) -> NodeIndex<usize>; fn node_index(&self) -> NodeIndex<usize>;
} }
#[enum_dispatch(GetNodeIndex)] #[enum_dispatch]
pub trait MakePrimitive {
fn primitive<'a>(&self, graph: &'a StableDiGraph<Weight, Label, usize>) -> Primitive<'a>;
}
#[enum_dispatch(GetNodeIndex, MakePrimitive)]
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] #[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
pub enum Index { pub enum Index {
Dot(DotIndex), Dot(DotIndex),
@ -123,5 +131,25 @@ macro_rules! untag {
} }
pub type DotIndex = GenericIndex<DotWeight>; pub type DotIndex = GenericIndex<DotWeight>;
impl MakePrimitive for DotIndex {
fn primitive<'a>(&self, graph: &'a StableDiGraph<Weight, Label, usize>) -> Primitive<'a> {
Primitive::Dot(GenericPrimitive::new(*self, graph))
}
}
pub type SegIndex = GenericIndex<SegWeight>; pub type SegIndex = GenericIndex<SegWeight>;
impl MakePrimitive for SegIndex {
fn primitive<'a>(&self, graph: &'a StableDiGraph<Weight, Label, usize>) -> Primitive<'a> {
Primitive::Seg(GenericPrimitive::new(*self, graph))
}
}
pub type BendIndex = GenericIndex<BendWeight>; pub type BendIndex = GenericIndex<BendWeight>;
impl MakePrimitive for BendIndex {
fn primitive<'a>(&self, graph: &'a StableDiGraph<Weight, Label, usize>) -> Primitive<'a> {
Primitive::Bend(GenericPrimitive::new(*self, graph))
}
}

View File

@ -12,7 +12,7 @@ use crate::graph::{
BendIndex, BendWeight, DotIndex, DotWeight, GenericIndex, GetNodeIndex, Index, Interior, Label, BendIndex, BendWeight, DotIndex, DotWeight, GenericIndex, GetNodeIndex, Index, Interior, Label,
Retag, SegIndex, SegWeight, Weight, Retag, SegIndex, SegWeight, Weight,
}; };
use crate::primitive::{GenericPrimitive, GetWeight, MakeShape}; use crate::primitive::{GenericPrimitive, GetWeight, MakeShape, TaggedPrevTaggedNext};
use crate::segbend::Segbend; use crate::segbend::Segbend;
use crate::shape::{Shape, ShapeTrait}; use crate::shape::{Shape, ShapeTrait};

View File

@ -11,6 +11,12 @@ use crate::graph::{
use crate::math::{self, Circle}; use crate::math::{self, Circle};
use crate::shape::{BendShape, DotShape, SegShape, Shape, ShapeTrait}; use crate::shape::{BendShape, DotShape, SegShape, Shape, ShapeTrait};
#[enum_dispatch]
pub trait TaggedPrevTaggedNext {
fn tagged_prev(&self) -> Option<Index>;
fn tagged_next(&self) -> Option<Index>;
}
#[enum_dispatch] #[enum_dispatch]
pub trait GetWeight<W> { pub trait GetWeight<W> {
fn weight(&self) -> W; fn weight(&self) -> W;
@ -21,7 +27,7 @@ pub trait MakeShape {
fn shape(&self) -> Shape; fn shape(&self) -> Shape;
} }
#[enum_dispatch(MakeShape)] #[enum_dispatch(MakeShape, TaggedPrevTaggedNext)]
pub enum Primitive<'a> { pub enum Primitive<'a> {
Dot(Dot<'a>), Dot(Dot<'a>),
Seg(Seg<'a>), Seg(Seg<'a>),
@ -74,11 +80,6 @@ impl<'a, W> GenericPrimitive<'a, W> {
None None
} }
pub fn tagged_prev(&self) -> Option<Index> {
self.prev_node()
.map(|ni| self.graph.node_weight(ni).unwrap().retag(ni))
}
fn prev_node(&self) -> Option<NodeIndex<usize>> { fn prev_node(&self) -> Option<NodeIndex<usize>> {
self.graph self.graph
.neighbors_directed(self.index.node_index(), Incoming) .neighbors_directed(self.index.node_index(), Incoming)
@ -120,11 +121,6 @@ impl<'a, W> GenericPrimitive<'a, W> {
None None
} }
pub fn tagged_next(&self) -> Option<Index> {
self.next_node()
.map(|ni| self.graph.node_weight(ni).unwrap().retag(ni))
}
fn next_node(&self) -> Option<NodeIndex<usize>> { fn next_node(&self) -> Option<NodeIndex<usize>> {
self.graph self.graph
.neighbors_directed(self.index.node_index(), Outgoing) .neighbors_directed(self.index.node_index(), Outgoing)
@ -218,6 +214,18 @@ impl<'a, W> Ends<DotIndex, DotIndex> for GenericPrimitive<'a, W> {
} }
} }
impl<'a, W> TaggedPrevTaggedNext for GenericPrimitive<'a, W> {
fn tagged_prev(&self) -> Option<Index> {
self.prev_node()
.map(|ni| self.graph.node_weight(ni).unwrap().retag(ni))
}
fn tagged_next(&self) -> Option<Index> {
self.next_node()
.map(|ni| self.graph.node_weight(ni).unwrap().retag(ni))
}
}
pub type Dot<'a> = GenericPrimitive<'a, DotWeight>; pub type Dot<'a> = GenericPrimitive<'a, DotWeight>;
impl<'a> Dot<'a> { impl<'a> Dot<'a> {

View File

@ -2,7 +2,7 @@ use petgraph::stable_graph::StableDiGraph;
use crate::{ use crate::{
graph::{BendIndex, DotIndex, Ends, Index, Interior, Label, SegIndex, Weight}, graph::{BendIndex, DotIndex, Ends, Index, Interior, Label, SegIndex, Weight},
primitive::{Bend, Dot}, primitive::{Bend, Dot, TaggedPrevTaggedNext},
}; };
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]