// 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, R: 'a, C> { fn ref_(&self, context: &'a C) -> R; } #[enum_dispatch] pub trait GetPetgraphIndex { fn petgraph_index(&self) -> NodeIndex; } // 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 { pub fn new(index: NodeIndex) -> Self { Self { node_index: index, marker: PhantomData, } } } impl core::clone::Clone for GenericIndex { #[inline] fn clone(&self) -> Self { Self { node_index: self.node_index, marker: PhantomData, } } } impl core::marker::Copy for GenericIndex {} impl core::fmt::Debug for GenericIndex { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_tuple("GenericIndex") .field(&self.node_index.index()) .finish() } } 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 { fn partial_cmp(&self, other: &Self) -> Option { self.node_index.partial_cmp(&other.node_index) } } impl Ord for GenericIndex { fn cmp(&self, other: &Self) -> Ordering { self.node_index.cmp(&other.node_index) } } impl GetPetgraphIndex for GenericIndex { 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)) ); } }