// SPDX-FileCopyrightText: 2024 Topola contributors // // SPDX-License-Identifier: MIT use std::{cmp::Ordering, marker::PhantomData}; use enum_dispatch::enum_dispatch; use petgraph::stable_graph::NodeIndex; use serde::{Deserialize, Serialize}; pub trait MakeRef<'a, C> { type Output: 'a; fn ref_(&self, context: &'a C) -> Self::Output; } #[enum_dispatch] pub trait GetPetgraphIndex { fn petgraph_index(&self) -> NodeIndex; } impl GetPetgraphIndex for NodeIndex { #[inline(always)] fn petgraph_index(&self) -> NodeIndex { *self } } // unfortunately, as we don't want any restrictions on `W`, // we have to implement many traits ourselves, instead of using derive macros. #[derive(Deserialize, Serialize)] #[serde(bound = "")] #[serde(transparent)] pub struct GenericIndex { node_index: NodeIndex, #[serde(skip)] marker: PhantomData, } impl GenericIndex { #[inline] pub fn new(index: NodeIndex) -> Self { Self { node_index: index, marker: PhantomData, } } } impl core::clone::Clone for GenericIndex { #[inline(always)] fn clone(&self) -> Self { *self } } impl core::marker::Copy for GenericIndex {} impl core::fmt::Debug for GenericIndex { #[inline] fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { core::fmt::Display::fmt(&self.node_index.index(), f) } } impl PartialEq for GenericIndex { #[inline] fn eq(&self, oth: &Self) -> bool { self.node_index == oth.node_index } } impl Eq for GenericIndex {} impl PartialOrd for GenericIndex { #[inline(always)] fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Ord for GenericIndex { #[inline] fn cmp(&self, other: &Self) -> Ordering { self.node_index.cmp(&other.node_index) } } impl core::hash::Hash for GenericIndex { #[inline] fn hash(&self, state: &mut H) { self.node_index.hash(state); } } impl GetPetgraphIndex for GenericIndex { #[inline] fn petgraph_index(&self) -> NodeIndex { self.node_index } } #[cfg(test)] mod tests { use super::*; #[test] fn serializable_index() { assert_eq!( serde_json::to_string(&GenericIndex::<()>::new(NodeIndex::new(0))).unwrap(), "0" ); assert_eq!( serde_json::from_str::>("0").unwrap(), GenericIndex::new(NodeIndex::new(0)) ); } }