Skip to main content

m1nd_core/
builder.rs

1// === crates/m1nd-core/src/builder.rs ===
2
3use crate::error::M1ndResult;
4use crate::graph::Graph;
5use crate::types::{EdgeDirection, FiniteF32, NodeId, NodeType};
6
7/// Programmatic graph builder for non-code domains.
8/// Allows building graphs without going through file extractors.
9pub struct GraphBuilder {
10    graph: Graph,
11}
12
13impl GraphBuilder {
14    pub fn new() -> Self {
15        Self {
16            graph: Graph::new(),
17        }
18    }
19
20    pub fn with_capacity(nodes: usize, edges: usize) -> Self {
21        Self {
22            graph: Graph::with_capacity(nodes, edges),
23        }
24    }
25
26    /// Add a node with arbitrary type and metadata
27    pub fn add_node(
28        &mut self,
29        id: &str,
30        label: &str,
31        node_type: NodeType,
32        tags: &[&str],
33    ) -> M1ndResult<NodeId> {
34        self.graph.add_node(id, label, node_type, tags, 0.0, 0.3)
35    }
36
37    /// Add a node with full temporal data
38    pub fn add_node_with_temporal(
39        &mut self,
40        id: &str,
41        label: &str,
42        node_type: NodeType,
43        tags: &[&str],
44        timestamp: f64,
45        change_freq: f32,
46    ) -> M1ndResult<NodeId> {
47        self.graph
48            .add_node(id, label, node_type, tags, timestamp, change_freq)
49    }
50
51    /// Add a directed edge
52    pub fn add_edge(
53        &mut self,
54        source: NodeId,
55        target: NodeId,
56        relation: &str,
57        weight: f32,
58    ) -> M1ndResult<()> {
59        self.graph.add_edge(
60            source,
61            target,
62            relation,
63            FiniteF32::new(weight),
64            EdgeDirection::Forward,
65            false,
66            FiniteF32::new(weight * 0.8), // causal = 80% of weight
67        )?;
68        Ok(())
69    }
70
71    /// Add a bidirectional edge
72    pub fn add_bidi_edge(
73        &mut self,
74        source: NodeId,
75        target: NodeId,
76        relation: &str,
77        weight: f32,
78    ) -> M1ndResult<()> {
79        self.graph.add_edge(
80            source,
81            target,
82            relation,
83            FiniteF32::new(weight),
84            EdgeDirection::Bidirectional,
85            false,
86            FiniteF32::new(weight * 0.8),
87        )?;
88        Ok(())
89    }
90
91    /// Finalize and return the graph
92    pub fn finalize(mut self) -> M1ndResult<Graph> {
93        if self.graph.num_nodes() > 0 {
94            self.graph.finalize()?;
95        }
96        Ok(self.graph)
97    }
98}