use enum_dispatch::enum_dispatch; use petgraph::stable_graph::NodeIndex; use crate::{drawing::Drawing, graph::GetNodeIndex}; use super::{ bend::{FixedBendIndex, FixedBendWeight, LooseBendIndex, LooseBendWeight}, dot::{FixedDotIndex, FixedDotWeight, LooseDotIndex, LooseDotWeight}, primitive::Primitive, rules::RulesTrait, seg::{ FixedSegIndex, FixedSegWeight, LoneLooseSegIndex, LoneLooseSegWeight, SeqLooseSegIndex, SeqLooseSegWeight, }, }; #[enum_dispatch] pub trait Retag { fn retag(&self, index: NodeIndex) -> PrimitiveIndex; } #[enum_dispatch] pub trait GetLayer { fn layer(&self) -> u64; } #[enum_dispatch] pub trait GetMaybeNet { fn maybe_net(&self) -> Option; } #[enum_dispatch] pub trait MakePrimitive { fn primitive<'a, CW: Copy, R: RulesTrait>( &self, drawing: &'a Drawing, ) -> Primitive<'a, CW, R>; } macro_rules! impl_weight { ($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => { impl Retag for $weight_struct { fn retag(&self, index: NodeIndex) -> PrimitiveIndex { PrimitiveIndex::$weight_variant($index_struct::new(index)) } } impl<'a> GetLayer for $weight_struct { fn layer(&self) -> u64 { self.layer } } impl<'a> GetMaybeNet for $weight_struct { fn maybe_net(&self) -> Option { self.maybe_net } } pub type $index_struct = GenericIndex<$weight_struct>; impl MakePrimitive for $index_struct { fn primitive<'a, CW: Copy, R: RulesTrait>( &self, drawing: &'a Drawing, ) -> Primitive<'a, CW, R> { Primitive::$weight_variant(GenericPrimitive::new(*self, drawing)) } } }; } macro_rules! impl_fixed_weight { ($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => { impl_weight!($weight_struct, $weight_variant, $index_struct); }; } macro_rules! impl_loose_weight { ($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => { impl_weight!($weight_struct, $weight_variant, $index_struct); }; } #[enum_dispatch(GetNodeIndex, MakePrimitive)] #[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)] pub enum PrimitiveIndex { FixedDot(FixedDotIndex), LooseDot(LooseDotIndex), FixedSeg(FixedSegIndex), LoneLooseSeg(LoneLooseSegIndex), SeqLooseSeg(SeqLooseSegIndex), FixedBend(FixedBendIndex), LooseBend(LooseBendIndex), } #[enum_dispatch(GetWidth, GetLayer, Retag)] #[derive(Debug, Clone, Copy, PartialEq)] pub enum PrimitiveWeight { FixedDot(FixedDotWeight), LooseDot(LooseDotWeight), FixedSeg(FixedSegWeight), LoneLooseSeg(LoneLooseSegWeight), SeqLooseSeg(SeqLooseSegWeight), FixedBend(FixedBendWeight), LooseBend(LooseBendWeight), }