bidirected_adjacency_array/
index.rs1use std::{
2 fmt::{Debug, Display},
3 hash::Hash,
4};
5
6use num_traits::{Bounded, PrimInt};
7use optional_numeric_index::implement_generic_index;
8
9pub trait GraphIndexInteger:
10 PrimInt + Bounded + Hash + Debug + Display + From<u8> + TryFrom<usize> + TryInto<usize>
11{
12}
13
14impl<T: PrimInt + Bounded + Hash + Debug + Display + From<u8> + TryFrom<usize> + TryInto<usize>>
15 GraphIndexInteger for T
16{
17}
18
19implement_generic_index!(pub NodeIndex, pub OptionalNodeIndex);
20implement_generic_index!(pub EdgeIndex, pub OptionalEdgeIndex);
21
22implement_generic_index!(pub DirectedNodeIndex, pub OptionalDirectedNodeIndex);
23implement_generic_index!(pub DirectedEdgeIndex, pub OptionalDirectedEdgeIndex);
24
25impl<IndexType: GraphIndexInteger> NodeIndex<IndexType> {
26 pub fn into_directed(self, forward: bool) -> DirectedNodeIndex<IndexType> {
27 DirectedNodeIndex::from_bidirected(self, forward)
28 }
29
30 pub fn into_directed_forward(self) -> DirectedNodeIndex<IndexType> {
31 self.into_directed(true)
32 }
33
34 pub fn into_directed_reverse(self) -> DirectedNodeIndex<IndexType> {
35 self.into_directed(false)
36 }
37}
38
39impl<IndexType: GraphIndexInteger> DirectedNodeIndex<IndexType> {
40 pub fn from_bidirected(bidirected: NodeIndex<IndexType>, forward: bool) -> Self {
41 let base = bidirected.0 * 2u8.into();
42 if forward {
43 DirectedNodeIndex(base)
44 } else {
45 DirectedNodeIndex(base + 1u8.into())
46 }
47 }
48
49 pub fn into_bidirected(self) -> NodeIndex<IndexType> {
50 NodeIndex(self.0 / 2u8.into())
51 }
52
53 pub fn invert(self) -> Self {
54 DirectedNodeIndex(self.0 ^ 1u8.into())
55 }
56
57 pub fn is_forward(self) -> bool {
58 (self.0 & 1u8.into()) == 0u8.into()
59 }
60
61 pub fn is_reverse(self) -> bool {
62 !self.is_forward()
63 }
64
65 pub(crate) fn add(self, other: DirectedNodeIndex<IndexType>) -> DirectedNodeIndex<IndexType> {
66 Self::new(self.0 + other.0)
67 }
68
69 pub fn with_bidirected_node_index(self, bidirected: NodeIndex<IndexType>) -> Self {
71 Self::from_bidirected(bidirected, self.is_forward())
72 }
73}
74
75impl<IndexType: GraphIndexInteger> DirectedEdgeIndex<IndexType> {
76 pub(crate) fn zero() -> Self {
77 Self::new(0u8.into())
78 }
79
80 pub(crate) fn increment(&mut self) {
81 *self = Self::new(self.0 + 1u8.into());
82 }
83
84 pub(crate) fn decrement(&mut self) {
85 *self = Self::new(self.0 - 1u8.into());
86 }
87
88 pub(crate) fn add(self, other: DirectedEdgeIndex<IndexType>) -> DirectedEdgeIndex<IndexType> {
89 Self::new(self.0 + other.0)
90 }
91}