1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
use std::{
    cmp::{max, min},
    ops::Range,
};

use std::fmt::{Display, Formatter};

pub mod actions;
pub mod typed_edges;

mod simple;

pub mod mut_iter;

/// used to determine the direction of an edge
pub type EdgeID = usize;

/// Marker trait for edges
///
/// # Examples
///
/// ```
/// use graph_theory::GraphEngine;
/// ```
pub trait Edge: Display {
    /// Whether the edge is bidirectional
    ///
    /// # Examples
    ///
    /// ```
    /// use graph_theory::DirectedEdge;
    /// ```
    fn direction(&self) -> EdgeDirection;
    /// The left side node id of the edge
    ///
    /// # Examples
    ///
    /// ```
    /// use graph_theory::GraphEngine;
    /// ```
    fn lhs(&self) -> usize;
    /// The right side node id of the edge
    ///
    /// # Examples
    ///
    /// ```
    /// use graph_theory::GraphEngine;
    /// ```
    fn rhs(&self) -> usize;
    /// The smaller of the two indices.
    ///
    /// # Examples
    ///
    /// ```
    /// use graph_theory::{Edge, UndirectedEdge};
    /// assert_eq!(UndirectedEdge::new(1, 2).max_index(), 2);
    /// assert_eq!(UndirectedEdge::new(2, 1).max_index(), 2);
    /// ```
    fn max_index(&self) -> usize {
        max(self.lhs(), self.rhs())
    }
    /// The smaller of the two indices.
    ///
    /// # Examples
    ///
    /// ```
    /// use graph_theory::{Edge, UndirectedEdge};
    /// assert_eq!(UndirectedEdge::new(1, 2).min_index(), 1);
    /// assert_eq!(UndirectedEdge::new(2, 1).min_index(), 1);
    /// ```
    fn min_index(&self) -> usize {
        min(self.lhs(), self.rhs())
    }

    /// The smaller of the two indices.
    ///
    /// # Examples
    ///
    /// ```
    /// use graph_theory::{Edge, UndirectedEdge};
    /// assert_eq!(UndirectedEdge::new(1, 3).delta_index(), 2);
    /// assert_eq!(UndirectedEdge::new(3, 1).delta_index(), 2);
    /// ```
    fn delta_index(&self) -> usize {
        self.max_index() - self.min_index()
    }
}

/// Determines the direction between two nodes
///
/// ```
/// use graph_theory::GraphEngine;
/// ```
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EdgeDirection {
    /// Two nodes that are not connected.
    Disconnect,
    /// [EdgeDirection::Forward] in a directed graph, [EdgeDirection::TwoWay] in an undirected graph
    Indeterminate,
    /// This edge is bidirectional
    TwoWay,
    /// This edge is unidirectional
    Forward,
    /// This edge is unidirectional and goes in the opposite direction
    Reverse,
}