diff --git a/src/graph.rs b/src/graph.rs index 3834f8c..4de4fdd 100644 --- a/src/graph.rs +++ b/src/graph.rs @@ -27,30 +27,30 @@ pub trait GetNet { } macro_rules! impl_type { - ($weight_struct_name:ident, $weight_variant_name:ident, $index_struct_name:ident) => { - impl Retag for $weight_struct_name { + ($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => { + impl Retag for $weight_struct { fn retag(&self, index: NodeIndex) -> Index { - Index::$weight_variant_name($index_struct_name { + Index::$weight_variant($index_struct { node_index: index, marker: PhantomData, }) } } - impl GetNet for $weight_struct_name { + impl GetNet for $weight_struct { fn net(&self) -> i64 { self.net } } - pub type $index_struct_name = GenericIndex<$weight_struct_name>; + pub type $index_struct = GenericIndex<$weight_struct>; - impl MakePrimitive for $index_struct_name { + impl MakePrimitive for $index_struct { fn primitive<'a>( &self, graph: &'a StableDiGraph, ) -> Primitive<'a> { - Primitive::$weight_variant_name(GenericPrimitive::new(*self, graph)) + Primitive::$weight_variant(GenericPrimitive::new(*self, graph)) } } }; @@ -137,6 +137,8 @@ impl From for Index { } } +pub trait DotWeight: GetNet + Into + Copy {} + #[derive(Debug, Clone, Copy, PartialEq)] pub struct FixedDotWeight { pub net: i64, @@ -144,6 +146,7 @@ pub struct FixedDotWeight { } impl_type!(FixedDotWeight, FixedDot, FixedDotIndex); +impl DotWeight for FixedDotWeight {} #[derive(Debug, Clone, Copy, PartialEq)] pub struct LooseDotWeight { @@ -152,6 +155,9 @@ pub struct LooseDotWeight { } impl_type!(LooseDotWeight, LooseDot, LooseDotIndex); +impl DotWeight for LooseDotWeight {} + +pub trait SegWeight: GetNet + Into + Copy {} #[derive(Debug, Clone, Copy, PartialEq)] pub struct FixedSegWeight { @@ -160,6 +166,7 @@ pub struct FixedSegWeight { } impl_type!(FixedSegWeight, FixedSeg, FixedSegIndex); +impl SegWeight for FixedSegWeight {} #[derive(Debug, Clone, Copy, PartialEq)] pub struct HalfLooseSegWeight { @@ -168,6 +175,7 @@ pub struct HalfLooseSegWeight { } impl_type!(HalfLooseSegWeight, HalfLooseSeg, HalfLooseSegIndex); +impl SegWeight for HalfLooseSegWeight {} #[derive(Debug, Clone, Copy, PartialEq)] pub struct FullyLooseSegWeight { @@ -176,6 +184,9 @@ pub struct FullyLooseSegWeight { } impl_type!(FullyLooseSegWeight, FullyLooseSeg, FullyLooseSegIndex); +impl SegWeight for FullyLooseSegWeight {} + +pub trait BendWeight: GetNet + Into + Copy {} #[derive(Debug, Clone, Copy, PartialEq)] pub struct FixedBendWeight { @@ -184,6 +195,7 @@ pub struct FixedBendWeight { } impl_type!(FixedBendWeight, FixedBend, FixedBendIndex); +impl BendWeight for FixedBendWeight {} #[derive(Debug, Clone, Copy, PartialEq)] pub struct LooseBendWeight { @@ -192,6 +204,7 @@ pub struct LooseBendWeight { } impl_type!(LooseBendWeight, LooseBend, LooseBendIndex); +impl BendWeight for LooseBendWeight {} #[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] pub enum Label { diff --git a/src/layout.rs b/src/layout.rs index ff77264..4bdff32 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -8,9 +8,10 @@ use rstar::{RTree, RTreeObject}; use crate::bow::Bow; use crate::graph::{ - FixedBendIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, FixedSegIndex, FixedSegWeight, - GenericIndex, GetNodeIndex, HalfLooseSegWeight, Index, Interior, Label, LooseDotIndex, - LooseDotWeight, MakePrimitive, Retag, Weight, + BendWeight, DotIndex, DotWeight, FixedBendIndex, FixedBendWeight, FixedDotIndex, + FixedDotWeight, FixedSegIndex, FixedSegWeight, FullyLooseSegIndex, FullyLooseSegWeight, + GenericIndex, GetNodeIndex, HalfLooseSegIndex, HalfLooseSegWeight, Index, Interior, Label, + LooseDotIndex, LooseDotWeight, LooseSegIndex, MakePrimitive, Retag, SegWeight, Weight, }; use crate::primitive::{GenericPrimitive, GetConnectable, GetWeight, MakeShape}; use crate::segbend::Segbend; @@ -64,9 +65,17 @@ impl Layout { self.graph.remove_node(index.node_index()); } - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))] + #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))] pub fn add_fixed_dot(&mut self, weight: FixedDotWeight) -> Result { - let dot = FixedDotIndex::new(self.graph.add_node(weight.into())); + self.add_dot(weight) + } + + #[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))] + fn add_dot(&mut self, weight: W) -> Result, ()> + where + GenericIndex: Into + Copy, + { + let dot = GenericIndex::::new(self.graph.add_node(weight.into())); self.insert_into_rtree(dot.into()); self.fail_and_remove_if_collides_except(dot.into(), &[])?; @@ -74,93 +83,59 @@ impl Layout { Ok(dot) } - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))] - pub fn add_loose_dot(&mut self, weight: LooseDotWeight) -> Result { - let dot = LooseDotIndex::new(self.graph.add_node(weight.into())); - - self.insert_into_rtree(dot.into()); - self.fail_and_remove_if_collides_except(dot.into(), &[])?; - - Ok(dot) - } - - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))] - #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count() + 2))] + #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))] + #[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 2))] + #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] + #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] pub fn add_fixed_seg( &mut self, from: FixedDotIndex, to: FixedDotIndex, weight: FixedSegWeight, ) -> Result { - let seg = FixedSegIndex::new(self.graph.add_node(weight.into())); - - self.graph - .add_edge(from.node_index(), seg.node_index(), Label::Adjacent); - self.graph - .add_edge(seg.node_index(), to.node_index(), Label::Adjacent); - - self.insert_into_rtree(seg.into()); - self.fail_and_remove_if_collides_except(seg.into(), &[])?; - - self.graph - .node_weight_mut(from.node_index()) - .unwrap() - .as_fixed_dot_mut() - .unwrap() - .net = weight.net; - self.graph - .node_weight_mut(to.node_index()) - .unwrap() - .as_fixed_dot_mut() - .unwrap() - .net = weight.net; - - Ok(seg) + self.add_seg(from, to, weight) } - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))] - #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count() + 2))] + #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))] + #[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 2))] + #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] + #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] pub fn add_half_loose_seg( &mut self, from: FixedDotIndex, to: LooseDotIndex, weight: HalfLooseSegWeight, - ) -> Result { - let seg = FixedSegIndex::new(self.graph.add_node(weight.into())); - - self.graph - .add_edge(from.node_index(), seg.node_index(), Label::Adjacent); - self.graph - .add_edge(seg.node_index(), to.node_index(), Label::Adjacent); - - self.insert_into_rtree(seg.into()); - self.fail_and_remove_if_collides_except(seg.into(), &[])?; - - self.graph - .node_weight_mut(from.node_index()) - .unwrap() - .as_fixed_dot_mut() - .unwrap() - .net = weight.net; - self.graph - .node_weight_mut(to.node_index()) - .unwrap() - .as_fixed_dot_mut() - .unwrap() - .net = weight.net; - - Ok(seg) + ) -> Result { + self.add_seg(from, to, weight) } - #[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))] - #[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count() + 2))] - pub fn add_loose_seg( + #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))] + #[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 2))] + #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] + #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] + pub fn add_fully_loose_seg( &mut self, from: LooseDotIndex, to: LooseDotIndex, - weight: HalfLooseSegWeight, - ) -> Result { - let seg = FixedSegIndex::new(self.graph.add_node(weight.into())); + weight: FullyLooseSegWeight, + ) -> Result { + self.add_seg(from, to, weight) + } + + #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))] + #[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 2))] + #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] + #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] + fn add_seg( + &mut self, + from: impl GetNodeIndex, + to: impl GetNodeIndex, + weight: W, + ) -> Result, ()> + where + GenericIndex: Into + Copy, + { + let seg = GenericIndex::::new(self.graph.add_node(weight.into())); self.graph .add_edge(from.node_index(), seg.node_index(), Label::Adjacent); @@ -175,13 +150,13 @@ impl Layout { .unwrap() .as_fixed_dot_mut() .unwrap() - .net = weight.net; + .net = weight.net(); self.graph .node_weight_mut(to.node_index()) .unwrap() .as_fixed_dot_mut() .unwrap() - .net = weight.net; + .net = weight.net(); Ok(seg) } @@ -202,7 +177,7 @@ impl Layout { } } - /*#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))] + #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))] #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] pub fn add_loose_bend( &mut self, @@ -216,19 +191,22 @@ impl Layout { Index::FixedBend(around) => self.add_outer_bend(from, to, around, weight), _ => unreachable!(), } - }*/ + } #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))] #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] #[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 3))] #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] - pub fn add_core_bend( + fn add_core_bend( &mut self, - from: FixedDotIndex, - to: FixedDotIndex, + from: impl GetNodeIndex, + to: impl GetNodeIndex, core: FixedDotIndex, - weight: FixedBendWeight, - ) -> Result { + weight: W, + ) -> Result + where + GenericIndex: Into + Copy, + { let bend = FixedBendIndex::new(self.graph.add_node(weight.into())); self.graph @@ -247,12 +225,12 @@ impl Layout { #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] #[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 4))] #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] - pub fn add_outer_bend( + fn add_outer_bend( &mut self, - from: FixedDotIndex, - to: FixedDotIndex, - inner: FixedBendIndex, - weight: FixedBendWeight, + from: impl GetNodeIndex, + to: impl GetNodeIndex, + inner: impl GetNodeIndex, + weight: W, ) -> Result { let core = *self .graph