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}