weavatrix_graph/graph/
builder.rs1use super::core::Graph;
2use super::index::canonicalize_edges;
3use super::validate::{validate_edge, validate_node};
4use crate::{Edge, GraphError, Node, NodeId, Result};
5use std::collections::HashMap;
6
7#[derive(Debug, Default)]
8pub struct GraphBuilder {
9 nodes: HashMap<NodeId, Node>,
10 edges: Vec<Edge>,
11}
12
13impl GraphBuilder {
14 #[must_use]
15 pub fn new() -> Self {
16 Self {
17 nodes: HashMap::new(),
18 edges: Vec::new(),
19 }
20 }
21
22 #[must_use]
24 pub fn with_capacity(nodes: usize, edges: usize) -> Self {
25 Self {
26 nodes: HashMap::with_capacity(nodes),
27 edges: Vec::with_capacity(edges),
28 }
29 }
30
31 pub fn add_node(&mut self, node: Node) -> Result<&mut Self> {
38 validate_node(&node)?;
39 if let Some(existing) = self.nodes.get(&node.id) {
40 if existing == &node {
41 return Ok(self);
42 }
43 return Err(GraphError::ConflictingNode {
44 id: node.id.to_string(),
45 });
46 }
47 self.nodes.insert(node.id.clone(), node);
48 Ok(self)
49 }
50
51 pub fn add_edge(&mut self, edge: Edge) -> Result<&mut Self> {
58 validate_edge(&edge)?;
59 self.edges.push(edge);
60 Ok(self)
61 }
62
63 pub fn build(self) -> Result<Graph> {
69 let mut nodes = self.nodes.into_values().collect::<Vec<_>>();
70 nodes.sort_unstable_by(|left, right| left.id.cmp(&right.id));
71 let (edges, topology) = canonicalize_edges(&nodes, self.edges)?;
72 Ok(Graph::from_indexed_parts(nodes, edges, topology))
73 }
74}