From 87705653bdfa2900da474c92c72cd62fbaefd26d Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Sun, 28 Jan 2024 20:53:36 +0000 Subject: [PATCH] geometry: use narrower types for returned adjacents --- src/layout/bend.rs | 12 +++++++++ src/layout/dot.rs | 12 +++++++++ src/layout/geometry.rs | 61 ++++++++++++++++++++++++++++++++---------- src/layout/seg.rs | 13 +++++++++ src/primitive.rs | 47 +++++++++++++++++++++++--------- 5 files changed, 119 insertions(+), 26 deletions(-) diff --git a/src/layout/bend.rs b/src/layout/bend.rs index 52de6dc..1afa2f3 100644 --- a/src/layout/bend.rs +++ b/src/layout/bend.rs @@ -30,6 +30,18 @@ impl From for GeometryIndex { } } +impl TryFrom for BendIndex { + type Error = (); // TODO. + + fn try_from(index: GeometryIndex) -> Result { + match index { + GeometryIndex::FixedBend(index) => Ok(BendIndex::Fixed(index)), + GeometryIndex::LooseBend(index) => Ok(BendIndex::Loose(index)), + _ => unreachable!(), + } + } +} + #[enum_dispatch(GetOffset, GetWidth)] #[derive(Debug, Clone, Copy, PartialEq)] pub enum BendWeight { diff --git a/src/layout/dot.rs b/src/layout/dot.rs index 050d3fb..0af04c2 100644 --- a/src/layout/dot.rs +++ b/src/layout/dot.rs @@ -31,6 +31,18 @@ impl From for GeometryIndex { } } +impl TryFrom for DotIndex { + type Error = (); // TODO. + + fn try_from(index: GeometryIndex) -> Result { + match index { + GeometryIndex::FixedDot(index) => Ok(DotIndex::Fixed(index)), + GeometryIndex::LooseDot(index) => Ok(DotIndex::Loose(index)), + _ => unreachable!(), + } + } +} + #[enum_dispatch(GetPos, GetWidth)] #[derive(Debug, Clone, Copy, PartialEq)] pub enum DotWeight { diff --git a/src/layout/geometry.rs b/src/layout/geometry.rs index 8bff261..fbf60b2 100644 --- a/src/layout/geometry.rs +++ b/src/layout/geometry.rs @@ -152,7 +152,7 @@ pub struct Geometry< DW: DotWeightTrait + Copy, SW: SegWeightTrait + Copy, BW: BendWeightTrait + Copy, - GI: GetNodeIndex + Copy, + GI: GetNodeIndex + TryInto + TryInto + TryInto + Copy, DI: GetNodeIndex + Copy, SI: GetNodeIndex + Copy, BI: GetNodeIndex + Copy, @@ -173,7 +173,7 @@ impl< DW: DotWeightTrait + Copy, SW: SegWeightTrait + Copy, BW: BendWeightTrait + Copy, - GI: GetNodeIndex + Copy, + GI: GetNodeIndex + TryInto + TryInto + TryInto + Copy, DI: GetNodeIndex + Copy, SI: GetNodeIndex + Copy, BI: GetNodeIndex + Copy, @@ -267,11 +267,11 @@ impl< fn inner_radius(&self, bend: BI) -> f64 { let mut r = self.bend_weight(bend).offset(); - let mut rail = bend.node_index(); + let mut rail = bend; while let Some(inner) = self.inner(rail) { let weight: BW = self - .weight(inner) + .bend_weight(inner) .try_into() .unwrap_or_else(|_| unreachable!()); r += weight.width() + weight.offset(); @@ -342,7 +342,7 @@ impl< .unwrap() } - pub fn first_rail(&self, index: NodeIndex) -> Option> { + pub fn first_rail(&self, index: NodeIndex) -> Option { self.graph .neighbors_directed(index, Incoming) .filter(|node| { @@ -353,48 +353,81 @@ impl< GeometryLabel::Core ) }) + .map(|node| { + self.graph + .node_weight(node) + .unwrap() + .retag(node) + .try_into() + .unwrap_or_else(|_| unreachable!()) + }) .next() } - pub fn core(&self, index: NodeIndex) -> Option> { + pub fn core(&self, bend: BI) -> DI { self.graph - .neighbors(index) + .neighbors(bend.node_index()) .filter(|node| { matches!( self.graph - .edge_weight(self.graph.find_edge(index, *node).unwrap()) + .edge_weight(self.graph.find_edge(bend.node_index(), *node).unwrap()) .unwrap(), GeometryLabel::Core ) }) + .map(|node| { + self.graph + .node_weight(node) + .unwrap() + .retag(node) + .try_into() + .unwrap_or_else(|_| unreachable!()) + }) .next() + .unwrap() } - pub fn inner(&self, index: NodeIndex) -> Option> { + pub fn inner(&self, bend: BI) -> Option { self.graph - .neighbors_directed(index, Incoming) + .neighbors_directed(bend.node_index(), Incoming) .filter(|node| { matches!( self.graph - .edge_weight(self.graph.find_edge(*node, index).unwrap()) + .edge_weight(self.graph.find_edge(*node, bend.node_index()).unwrap()) .unwrap(), GeometryLabel::Outer ) }) + .map(|node| { + self.graph + .node_weight(node) + .unwrap() + .retag(node) + .try_into() + .unwrap_or_else(|_| unreachable!()) + }) .next() } - pub fn outer(&self, index: NodeIndex) -> Option> { + pub fn outer(&self, bend: BI) -> Option { self.graph - .neighbors_directed(index, Outgoing) + .neighbors_directed(bend.node_index(), Outgoing) .filter(|node| { matches!( self.graph - .edge_weight(self.graph.find_edge(index, *node).unwrap()) + .edge_weight(self.graph.find_edge(bend.node_index(), *node).unwrap()) .unwrap(), GeometryLabel::Outer ) }) + .map(|node| { + self.graph + .node_weight(node) + .unwrap() + .retag(node) + .try_into() + .unwrap_or_else(|_| unreachable!()) + }) .next() } diff --git a/src/layout/seg.rs b/src/layout/seg.rs index 78a3f45..48f86b8 100644 --- a/src/layout/seg.rs +++ b/src/layout/seg.rs @@ -31,6 +31,19 @@ impl From for GeometryIndex { } } +impl TryFrom for SegIndex { + type Error = (); // TODO. + + fn try_from(index: GeometryIndex) -> Result { + match index { + GeometryIndex::FixedSeg(index) => Ok(SegIndex::Fixed(index)), + GeometryIndex::LoneLooseSeg(index) => Ok(SegIndex::LoneLoose(index)), + GeometryIndex::SeqLooseSeg(index) => Ok(SegIndex::SeqLoose(index)), + _ => unreachable!(), + } + } +} + #[enum_dispatch(GetWidth)] #[derive(Debug, Clone, Copy, PartialEq)] pub enum SegWeight { diff --git a/src/primitive.rs b/src/primitive.rs index c68d8c6..b078a9b 100644 --- a/src/primitive.rs +++ b/src/primitive.rs @@ -88,33 +88,38 @@ pub trait GetFirstRail: GetLayout + GetNodeIndex { self.layout() .geometry() .first_rail(self.node_index()) - .map(|node| LooseBendIndex::new(node)) + .map(|node| LooseBendIndex::new(node.node_index())) } } -pub trait GetCore: GetLayout + GetNodeIndex { +pub trait GetBendIndex { + fn bend_index(&self) -> BendIndex; +} + +pub trait GetCore: GetLayout + GetBendIndex { fn core(&self) -> FixedDotIndex { - self.layout() - .geometry() - .core(self.node_index()) - .map(|node| FixedDotIndex::new(node)) - .unwrap() + FixedDotIndex::new( + self.layout() + .geometry() + .core(self.bend_index()) + .node_index(), + ) } } -pub trait GetInnerOuter: GetLayout + GetNodeIndex { +pub trait GetInnerOuter: GetLayout + GetBendIndex { fn inner(&self) -> Option { self.layout() .geometry() - .inner(self.node_index()) - .map(|node| LooseBendIndex::new(node)) + .inner(self.bend_index()) + .map(|node| LooseBendIndex::new(node.node_index())) } fn outer(&self) -> Option { self.layout() .geometry() - .outer(self.node_index()) - .map(|node| LooseBendIndex::new(node)) + .outer(self.bend_index()) + .map(|node| LooseBendIndex::new(node.node_index())) } } @@ -446,6 +451,12 @@ impl<'a> GetOtherEnd for SeqLooseSeg<'a> {} pub type FixedBend<'a> = GenericPrimitive<'a, FixedBendWeight>; impl_fixed_primitive!(FixedBend, FixedBendWeight); +impl<'a> GetBendIndex for FixedBend<'a> { + fn bend_index(&self) -> BendIndex { + self.index.into() + } +} + impl<'a> MakeShape for FixedBend<'a> { fn shape(&self) -> Shape { self.layout.geometry().bend_shape(self.index.into()) @@ -469,6 +480,18 @@ impl<'a> GetCore for FixedBend<'a> {} // TODO: Fixed bends don't have cores actu pub type LooseBend<'a> = GenericPrimitive<'a, LooseBendWeight>; impl_loose_primitive!(LooseBend, LooseBendWeight); +impl<'a> GetBendIndex for LooseBend<'a> { + fn bend_index(&self) -> BendIndex { + self.index.into() + } +} + +impl<'a> From> for BendIndex { + fn from(bend: LooseBend<'a>) -> BendIndex { + bend.index.into() + } +} + impl<'a> MakeShape for LooseBend<'a> { fn shape(&self) -> Shape { self.layout.geometry().bend_shape(self.index.into())