pub struct Graph {
pub project: Option<ProjectMeta>,
pub nodes: Vec<Node>,
pub edges: Vec<Edge>,
}Expand description
A complete GID graph with nodes and edges.
Fields§
§project: Option<ProjectMeta>§nodes: Vec<Node>§edges: Vec<Edge>Implementations§
Source§impl Graph
impl Graph
pub fn new() -> Self
pub fn get_node(&self, id: &str) -> Option<&Node>
pub fn get_node_mut(&mut self, id: &str) -> Option<&mut Node>
pub fn add_node(&mut self, node: Node)
pub fn remove_node(&mut self, id: &str) -> Option<Node>
pub fn update_status(&mut self, id: &str, status: NodeStatus) -> bool
pub fn add_edge(&mut self, edge: Edge)
pub fn remove_edge(&mut self, from: &str, to: &str, relation: Option<&str>)
Sourcepub fn add_edge_dedup(&mut self, edge: Edge) -> bool
pub fn add_edge_dedup(&mut self, edge: Edge) -> bool
Add an edge with deduplication check.
Returns true if the edge was added (new), false if it already existed.
An edge is considered duplicate if the (from, to, relation) triple matches.
§Examples
use gid_core::{Graph, Edge};
let mut g = Graph::new();
let edge = Edge::new("a", "b", "depends_on");
assert!(g.add_edge_dedup(edge.clone())); // Returns true (new edge)
assert!(!g.add_edge_dedup(edge)); // Returns false (duplicate)Sourcepub fn add_feature(&mut self, name: &str, tasks: &[TaskSpec]) -> String
pub fn add_feature(&mut self, name: &str, tasks: &[TaskSpec]) -> String
Create a feature node with task nodes and all edges in one operation.
- Creates
feat-{slug}feature node - Creates
task-{feature_slug}-{task_slug}task nodes - Adds
implementsedges from each task to the feature - Adds
depends_onedges between tasks per TaskSpec.deps (matched by title) - Returns the feature node ID
Sourcepub fn add_task(
&mut self,
title: &str,
for_feature: Option<&str>,
depends_on: &[String],
tags: &[String],
priority: Option<u8>,
) -> String
pub fn add_task( &mut self, title: &str, for_feature: Option<&str>, depends_on: &[String], tags: &[String], priority: Option<u8>, ) -> String
Add a standalone task node (no parent feature required). Returns the task node ID.
Sourcepub fn merge_feature_nodes(
&mut self,
feature_id: &str,
incoming: Graph,
) -> (usize, usize)
pub fn merge_feature_nodes( &mut self, feature_id: &str, incoming: Graph, ) -> (usize, usize)
Merge incoming nodes into this graph, scoped to a specific feature.
- Finds all existing task nodes that
implementsthe target feature - Removes those old task nodes (cascading edge cleanup via remove_node)
- Adds all incoming nodes
- Adds
implementsedges from incoming task nodes to the feature - Adds incoming edges with deduplication
Returns (removed_count, added_count) for reporting.
Sourcepub fn resolve_node(&self, reference: &str) -> Vec<&Node>
pub fn resolve_node(&self, reference: &str) -> Vec<&Node>
Resolve a node reference to actual node(s) using a 7-tier priority cascade.
Priority tiers (highest to lowest):
- Exact ID match
- Exact title match (case-insensitive)
- Structural segment match (
:,-,/delimiters) - Word segment match (
_delimiter) - File path match
- Title substring match (case-insensitive)
- ID substring match (case-insensitive)
Returns a vector of matching nodes. Empty vector if no match found. May return multiple nodes if there’s ambiguity (e.g., multiple substring matches).
§Examples
use gid_core::{Graph, Node};
let mut g = Graph::new();
g.add_node(Node::new("feat-auth", "Authentication Feature"));
g.add_node(Node::new("impl-jwt", "Implement JWT validation"));
// Exact ID match
let results = g.resolve_node("feat-auth");
assert_eq!(results.len(), 1);
assert_eq!(results[0].id, "feat-auth");
// Case-insensitive title match
let results = g.resolve_node("authentication feature");
assert_eq!(results.len(), 1);
// No match
let results = g.resolve_node("nonexistent");
assert_eq!(results.len(), 0);pub fn edges_from(&self, id: &str) -> Vec<&Edge>
pub fn edges_to(&self, id: &str) -> Vec<&Edge>
Sourcepub fn code_nodes(&self) -> Vec<&Node>
pub fn code_nodes(&self) -> Vec<&Node>
Get all code nodes (source == “extract”)
Sourcepub fn project_nodes(&self) -> Vec<&Node>
pub fn project_nodes(&self) -> Vec<&Node>
Get all project nodes (source == “project” or legacy None)
Sourcepub fn code_edges(&self) -> Vec<&Edge>
pub fn code_edges(&self) -> Vec<&Edge>
Get all code edges (source == “extract”)
Sourcepub fn project_edges(&self) -> Vec<&Edge>
pub fn project_edges(&self) -> Vec<&Edge>
Get all project edges (not code, not bridge)
Sourcepub fn bridge_edges(&self) -> Vec<&Edge>
pub fn bridge_edges(&self) -> Vec<&Edge>
Get all bridge edges (source == “auto-bridge”)
Sourcepub fn ready_tasks(&self) -> Vec<&Node>
pub fn ready_tasks(&self) -> Vec<&Node>
Get tasks that are ready (todo + all depends_on are done). Only considers project nodes; code nodes are excluded.
Uses pre-built HashMaps for O(N+M) instead of O(N×M×N).
Sourcepub fn tasks_by_status(&self, status: &NodeStatus) -> Vec<&Node>
pub fn tasks_by_status(&self, status: &NodeStatus) -> Vec<&Node>
Get tasks by status.
Sourcepub fn summary(&self) -> GraphSummary
pub fn summary(&self) -> GraphSummary
Summary statistics (counts only project nodes, not code nodes).
Sourcepub fn summary_text(&self) -> String
pub fn summary_text(&self) -> String
Get a human-readable text summary of the graph state.
Sourcepub fn health(&self) -> f64
pub fn health(&self) -> f64
Calculate graph health score (0.0 to 1.0).
Health is based on:
- Progress: ratio of done tasks to total
- Flow: ratio of ready tasks to remaining (non-blocked) tasks
- Connectivity: graphs with edges are healthier than isolated nodes
Returns 1.0 for a fully complete graph, 0.0 for an empty or stuck graph.
Sourcepub fn mark_task_done(&mut self, node_id: &str) -> bool
pub fn mark_task_done(&mut self, node_id: &str) -> bool
Mark a task as done. Returns true if found and updated.
Sourcepub fn get_executable_tasks(&self) -> Vec<Task>
pub fn get_executable_tasks(&self) -> Vec<Task>
Get executable tasks (alias for ready_tasks, returns owned Task structs).