mod graph_macros;
mod graph_serde;
mod node;
use std::{
fmt::{Display, Write},
hash::Hash,
};
use ahash::HashMap;
pub use self::node::*;
pub struct Graph<K, N, E>
where
K: Clone + Hash + Display + PartialEq + Eq,
N: Clone,
E: Clone,
{
nodes: HashMap<K, Node<K, N, E>>,
}
impl<K, N, E> Graph<K, N, E>
where
K: Clone + Hash + Display + PartialEq + Eq,
N: Clone,
E: Clone,
{
pub fn new() -> Self {
Self {
nodes: HashMap::default(),
}
}
pub fn contains(&self, key: &K) -> bool {
self.nodes.contains_key(key)
}
pub fn len(&self) -> usize {
self.nodes.len()
}
pub fn get(&self, key: &K) -> Option<Node<K, N, E>> {
self.nodes.get(key).cloned()
}
pub fn is_empty(&self) -> bool {
self.nodes.is_empty()
}
pub fn insert(&mut self, node: Node<K, N, E>) -> bool {
if self.nodes.contains_key(node.key()) {
false
} else {
self.nodes.insert(node.key().clone(), node.clone());
true
}
}
pub fn remove(&mut self, node: &K) -> Option<Node<K, N, E>> {
self.nodes.remove(node)
}
pub fn to_vec(&self) -> Vec<Node<K, N, E>> {
self.nodes.values().cloned().collect()
}
pub fn orphans(&self) -> Vec<Node<K, N, E>> {
self.nodes
.values()
.filter(|node| node.is_orphan())
.cloned()
.collect()
}
pub fn iter(&self) -> std::collections::hash_map::Iter<'_, K, Node<K, N, E>> {
self.nodes.iter()
}
pub fn to_dot(&self) -> String
where
N: Display,
E: Display,
{
let mut s = String::new();
s.push_str("digraph {\n");
for (u_key, node) in self.iter() {
write!(&mut s, " {}", u_key.clone()).unwrap();
for Edge(_, v, _) in node {
write!(&mut s, "\n {} -> {}", u_key, v.key()).unwrap();
}
s.push('\n');
}
s.push('}');
s
}
}
impl<K, N, E> std::ops::Index<K> for Graph<K, N, E>
where
K: Clone + Hash + Display + Eq,
N: Clone,
E: Clone,
{
type Output = Node<K, N, E>;
fn index(&self, key: K) -> &Self::Output {
&self.nodes[&key]
}
}
impl<K, N, E> Default for Graph<K, N, E>
where
K: Clone + Hash + Display + Eq,
N: Clone,
E: Clone,
{
fn default() -> Self {
Self::new()
}
}