smol_graph/
lib.rs

1#![doc = include_str!("../README.md")]
2
3use std::collections::HashMap;
4
5use uuid::Uuid;
6
7/// A graph generic over node and edge data.
8///
9/// Nodes and edges are public because this graph makes 
10/// no guarantees as to its structure beyond being a graph.
11///
12/// The graph does provide convenience functions for 
13/// some simple operations over its data.
14#[derive(Debug)]
15pub struct Graph<Node, EdgeData> {
16    pub nodes: HashMap<NodeIndex, Node>,
17    pub edges: HashMap<EdgeIndex, Edge<EdgeData>>,
18}
19
20/// A struct representing an edge between two nodes.
21#[derive(Debug, Clone)]
22pub struct Edge<Data> {
23    pub nodes: (NodeIndex, NodeIndex),
24    pub data: Data,
25}
26
27impl<Data> Edge<Data> {
28    /// Create a new edge with nodes and data.
29    pub fn new(nodes: (NodeIndex, NodeIndex), data: Data) -> Edge<Data> {
30        Edge {
31            nodes,
32            data,
33        }
34    }
35}
36
37/// An index pointing to a node in the graph.
38#[derive(Debug, Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
39pub struct NodeIndex(Uuid);
40
41/// An index pointing to an edge in the graph.
42#[derive(Debug, Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
43pub struct EdgeIndex(Uuid);
44
45impl NodeIndex {
46    /// Create a new node index.
47    pub fn new() -> NodeIndex {
48        NodeIndex(Uuid::new_v4())
49    }
50}
51
52impl EdgeIndex {
53    /// Create a new edge index.
54    pub fn new() -> EdgeIndex {
55        EdgeIndex(Uuid::new_v4())
56    }
57}
58
59impl<Node, EdgeData> Graph<Node, EdgeData> {
60    /// Create a new graph with empty nodes and edges.
61    /// 
62    /// To initialize with capacity or other pre-defined
63    /// settings, create it using public fields.
64    pub fn new() -> Self { 
65        Self { 
66            nodes: HashMap::new(), 
67            edges: HashMap::new() 
68        }
69    }
70
71    /// An iterator over this graph's nodes, in no
72    /// particular order.
73    pub fn nodes<'a>(&'a self) -> impl Iterator + 'a {
74        self.nodes.iter()
75    }
76
77    /// An iterator over this graph's edges, in no
78    /// particular order.
79    pub fn edges<'a>(&'a self) -> impl Iterator + 'a {
80        self.edges.iter()
81    }
82
83    /// A convenience function to insert an edge at a new index.
84    pub fn edge(&mut self, edge: Edge<EdgeData>) -> EdgeIndex {
85        let idx = EdgeIndex::new();
86        self.edges.insert(idx, edge);
87        idx
88    }
89
90    /// Attempt to remove an edge from this graph, returning it if it 
91    /// existed.
92    pub fn r_edge(&mut self, idx: EdgeIndex) -> Option<Edge<EdgeData>> {
93        self.edges.remove(&idx)
94    }
95
96    /// A convenience function to insert a node at a new index.
97    pub fn node(&mut self, node: Node) -> NodeIndex {
98        let idx = NodeIndex::new();
99        self.nodes.insert(idx, node);
100        idx
101    }
102
103    /// Attempt to remove a node from this graph, returning it if it 
104    /// existed.
105    ///
106    /// Note that this will *not* check if any edges still have the node
107    /// referenced.
108    pub fn r_node(&mut self, idx: NodeIndex) -> Option<Node> {
109        self.nodes.remove(&idx)
110    }
111}
112
113pub mod prelude {
114    pub use crate::{
115        Graph,
116        NodeIndex,
117        EdgeIndex,
118        Edge,
119    };
120}