prima/graphs/
edge.rs

1use super::{CellIndex, GraphData, NodeIndex};
2use crate::core::{DefaultIx, IndexType};
3
4/// An edge that connects two [`super::Node`]s and two [`super::Cell`]s together. Carries data for the end user.
5#[derive(Debug, Clone)]
6pub struct Edge<E, Ix = DefaultIx>
7where
8    Ix: IndexType,
9{
10    pub(crate) node_a: NodeIndex<Ix>,
11    pub(crate) node_b: NodeIndex<Ix>,
12    pub(crate) cell_a: CellIndex<Ix>,
13    // Optional to allow for the initiation of edge edges!
14    pub(crate) cell_b: Option<CellIndex<Ix>>,
15    /// The assosiated data attached to this Edge.
16    pub data: Option<Box<E>>,
17}
18
19impl<E, Ix> Edge<E, Ix>
20where
21    Ix: IndexType,
22{
23    /// Produces a new Edge with the given nodes, cells and optional data.
24    pub fn new(
25        node_a: NodeIndex<Ix>,
26        node_b: NodeIndex<Ix>,
27        cell_a: CellIndex<Ix>,
28        cell_b: CellIndex<Ix>,
29        data: Option<Box<E>>,
30    ) -> Self {
31        Self {
32            node_a,
33            node_b,
34            cell_a,
35            cell_b: Some(cell_b),
36            data,
37        }
38    }
39
40    /// Creates an edge that is only connected to one cell, rather than the typical two.
41    pub fn new_single_cell(
42        node_a: NodeIndex<Ix>,
43        node_b: NodeIndex<Ix>,
44        cell_a: CellIndex<Ix>,
45        data: Option<Box<E>>,
46    ) -> Self {
47        Self {
48            node_a,
49            node_b,
50            cell_a,
51            cell_b: None,
52            data,
53        }
54    }
55
56    /// If no second cell is set, adds given cell and returns [`true`], otherwise returns [`false`].
57    pub fn try_add_cell(&mut self, i: CellIndex<Ix>) -> bool {
58        if self.cell_b.is_none() {
59            self.cell_b = Some(i);
60            return true;
61        }
62        false
63    }
64
65    /// Returns the two nodes attached to this edge.
66    pub fn nodes(&self) -> (NodeIndex<Ix>, NodeIndex<Ix>) {
67        (self.node_a, self.node_b)
68    }
69    /// Given one of two nodes, returns its counterpart. Returns [`None`] if the given node is not found.
70    pub fn node_other(&self, i: NodeIndex<Ix>) -> Option<NodeIndex<Ix>> {
71        if i == self.node_a {
72            return Some(self.node_b);
73        } else if i == self.node_b {
74            return Some(self.node_a);
75        } else {
76            None
77        }
78    }
79    /// Returns the two cells that connect to this edge.
80    pub fn cells(&self) -> (CellIndex<Ix>, CellIndex<Ix>) {
81        (self.cell_a, self.cell_b.expect("msg"))
82    }
83    /// Given one of two cells, returns its counterpart. Returns [`None`] if the given cell is not found.
84    pub fn cell_other(&self, i: CellIndex<Ix>) -> Option<CellIndex<Ix>> {
85        if self.cell_b.is_none() {
86            return Some(self.cell_a);
87        }
88        if i == self.cell_a {
89            return Some(self.cell_b.unwrap());
90        } else if i == self.cell_b.unwrap() {
91            return Some(self.cell_a);
92        }
93        None
94    }
95
96    /// Returns true if the given cell index is part of this edge
97    pub fn touches_cell(&self, i: CellIndex<Ix>) -> bool {
98        if self.cell_b.is_some() {
99            return self.cell_b.unwrap() == i || self.cell_a == i;
100        }
101        self.cell_a == i
102    }
103}
104
105impl<E, Ix> PartialEq for Edge<E, Ix>
106where
107    Ix: IndexType,
108{
109    fn eq(&self, other: &Self) -> bool {
110        let nodes = (self.node_a == other.node_a && self.node_b == other.node_b) || (self.node_a == other.node_b && self.node_b == other.node_a);
111        let cells: bool;
112        if self.cell_b.is_some() == other.cell_b.is_some() {
113            // Both edges have the same number of cells
114            if self.cell_b.is_some() {
115                // Both edges have two cells
116                cells = (self.cell_a == other.cell_a && self.cell_b.unwrap() == other.cell_b.unwrap()) || (self.cell_a == other.cell_b.unwrap() && self.cell_b.unwrap() == other.cell_a);
117            } else {
118                // Both edges have one cell
119                cells = self.cell_a == other.cell_a;
120            }
121            return nodes && cells;
122        }
123        return false;
124    }
125}
126
127impl<E, Ix> GraphData<E> for Edge<E, Ix>
128where
129    Ix: IndexType,
130{
131    fn data(&self) -> Option<&Box<E>> {
132        if self.data.is_none() {
133            return None;
134        }
135        self.data.as_ref()
136    }
137
138    fn data_mut(&mut self) -> Option<&mut Box<E>> {
139        if self.data.is_none() {
140            return None;
141        }
142        self.data.as_mut()
143    }
144}