use std::{ rc::Rc, cell::RefCell, fmt::{self, Debug}, hash::{Hash, Hasher}, }; #[derive(Default)] pub struct Graph { pub nodes: Vec>, } impl Graph where T: Eq + Clone, W: Copy { pub fn add_edge(&mut self, edge: &(T, T, W)) { let (a, b, w) = edge; let mut node_a = { match self.nodes.iter().find(|&node| *node == *a) { Some(n) => n.to_owned(), None => { let new_node = Node::new(a.clone()); self.nodes.push(new_node.clone()); new_node } } }; let mut node_b = { match self.nodes.iter().find(|&node| *node == *b) { Some(n) => n.to_owned(), None => { let new_node = Node::new(b.clone()); self.nodes.push(new_node.clone()); new_node } } }; node_a.add_edge(node_b.clone(), *w); node_b.add_edge(node_a, *w); } } impl Debug for Graph where T: Debug, W: Debug { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { writeln!(f, "Graph {{")?; for node in &self.nodes { for (outgoing, weight) in &node.borrow().outgoing { writeln!(f, " {:?} -- [{:?}] -- {:?}", node.borrow().data, weight, outgoing.borrow().data)?; } } writeln!(f, "}}") } } pub struct Node(pub Rc>>); impl Node { pub fn new(data: T) -> Self { let inner = InnerNode { outgoing: Vec::new(), data }; Self(Rc::new(RefCell::new(inner))) } pub fn add_edge(&mut self, node: Self, weight: W) { self.0.borrow_mut().outgoing.push((node, weight)); } pub fn borrow(&self) -> std::cell::Ref<'_, InnerNode> { self.0.borrow() } } impl Clone for Node { fn clone(&self) -> Self { Self(self.0.clone()) } } impl Hash for Node where T: Hash { fn hash(&self, hasher: &mut H) { let this = self.borrow(); this.data.hash(hasher); } } impl PartialEq for Node where T: PartialEq { fn eq(&self, other: &T) -> bool { self.0.borrow().data == *other } } impl Eq for Node where T: Eq {} impl PartialEq for Node where T: PartialEq { fn eq(&self, other: &Self) -> bool { self.0.borrow().data == other.0.borrow().data } } impl Debug for Node where T: Debug, W: Debug { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Node") .field("data", &self.0.borrow().data) .finish() } } pub struct InnerNode { pub data: T, pub outgoing: Vec<(Node, W)>, }