gdsl/digraph/node/
adjacent.rs

1use super::*;
2
3use crate::error::Error;
4
5type InnerEdge<K, N, E> = (WeakNode<K, N, E>, E);
6type RefInnerEdge<'a, K, N, E> = (&'a WeakNode<K, N, E>, &'a E);
7type NodeInner<K, N, E> = (K, N, RefCell<Adjacent<K, N, E>>);
8
9#[derive(Clone)]
10pub struct WeakNode<K = usize, N = (), E = ()>
11where
12    K: Clone + Hash + Display + PartialEq + Eq,
13    N: Clone,
14    E: Clone,
15{
16    inner: Weak<NodeInner<K, N, E>>,
17}
18
19impl<K, N, E> WeakNode<K, N, E>
20where
21    K: Clone + Hash + Display + PartialEq + Eq,
22    N: Clone,
23    E: Clone,
24{
25    pub fn upgrade(&self) -> Option<Node<K, N, E>> {
26        self.inner.upgrade().map(|inner| Node { inner })
27    }
28
29    pub fn downgrade(node: &Node<K, N, E>) -> Self {
30        WeakNode {
31            inner: Rc::downgrade(&node.inner),
32        }
33    }
34}
35
36pub struct Adjacent<K, N, E>
37where
38    K: Clone + Hash + PartialEq + Eq + Display,
39    N: Clone,
40    E: Clone,
41{
42    pub outbound: Vec<InnerEdge<K, N, E>>,
43    inbound: Vec<InnerEdge<K, N, E>>,
44}
45
46impl<K, N, E> Adjacent<K, N, E>
47where
48    K: Clone + Hash + PartialEq + Eq + Display,
49    N: Clone,
50    E: Clone,
51{
52    pub fn new() -> RefCell<Self> {
53        RefCell::new(Self {
54            outbound: Vec::new(),
55            inbound: Vec::new(),
56        })
57    }
58
59    pub fn get_outbound(&self, idx: usize) -> Option<RefInnerEdge<K, N, E>> {
60        self.outbound.get(idx).map(|edge| (&edge.0, &edge.1))
61    }
62
63    pub fn get_inbound(&self, idx: usize) -> Option<RefInnerEdge<K, N, E>> {
64        self.inbound.get(idx).map(|edge| (&edge.0, &edge.1))
65    }
66
67    pub fn find_outbound(&self, node: &K) -> Option<RefInnerEdge<K, N, E>> {
68        for edge in self.outbound.iter() {
69            if edge.0.upgrade().unwrap().key() == node {
70                return Some((&edge.0, &edge.1));
71            }
72        }
73        None
74    }
75
76    pub fn find_inbound(&self, node: &K) -> Option<RefInnerEdge<K, N, E>> {
77        for edge in self.inbound.iter() {
78            if edge.0.upgrade().unwrap().key() == node {
79                return Some((&edge.0, &edge.1));
80            }
81        }
82        None
83    }
84
85    pub fn len_outbound(&self) -> usize {
86        self.outbound.len()
87    }
88
89    pub fn len_inbound(&self) -> usize {
90        self.inbound.len()
91    }
92
93    pub fn push_inbound(&mut self, edge: (Node<K, N, E>, E)) {
94        self.inbound.push((WeakNode::downgrade(&edge.0), edge.1));
95    }
96
97    pub fn push_outbound(&mut self, edge: (Node<K, N, E>, E)) {
98        self.outbound.push((WeakNode::downgrade(&edge.0), edge.1));
99    }
100
101    pub fn remove_inbound(&mut self, source: &K) -> Result<E, Error> {
102        for (idx, edge) in self.inbound.iter().enumerate() {
103            if edge.0.upgrade().unwrap().key() == source {
104                return Ok(self.inbound.remove(idx).1);
105            }
106        }
107        Err(Error::EdgeNotFound)
108    }
109
110    pub fn remove_outbound(&mut self, target: &K) -> Result<E, Error> {
111        for (idx, edge) in self.outbound.iter().enumerate() {
112            if edge.0.upgrade().unwrap().key() == target {
113                return Ok(self.outbound.remove(idx).1);
114            }
115        }
116        Err(Error::EdgeNotFound)
117    }
118
119    pub fn clear_inbound(&mut self) {
120        self.inbound.clear();
121    }
122
123    pub fn clear_outbound(&mut self) {
124        self.outbound.clear();
125    }
126
127    pub fn sizeof(&self) -> usize {
128        self.inbound.len()
129            + self.outbound.len()
130                * (std::mem::size_of::<Node<K, N, E>>() + std::mem::size_of::<E>())
131            + std::mem::size_of::<Self>()
132    }
133}