pub struct DagGraph<E> { /* private fields */ }Expand description
Directed acyclic graph generic over any E: Edge.
Rejects self-references and any edge whose insertion would
create a cycle in the active-edge subgraph. Wraps an
EdgeStore<E> to inherit archive / unarchive semantics for
soft-delete cascades.
Deserialize runs the DAG invariants against the active subset
of loaded edges; a corrupted file with a cycle or self-reference
fails to load up front rather than silently rehydrating into an
invariant-violating state.
The graph machinery is fully generic: external code can
instantiate DagGraph<MyEdge> for any MyEdge: Edge without
needing to modify this crate. The kanban-domain DependencyGraph
uses three concrete instantiations
(DagGraph<SpawnsEdge> / DagGraph<BlocksEdge> / etc.) but the
machinery itself is open for extension.
Implementations§
Source§impl<E: Edge> DagGraph<E>
impl<E: Edge> DagGraph<E>
pub fn new() -> Self
Sourcepub fn edges(&self) -> &[E]
pub fn edges(&self) -> &[E]
Borrow the raw underlying edge list (active + archived).
Persistence layers use this to serialise; size and membership
queries go through the EdgeSet trait surface.
Sourcepub fn add_edge_with_metadata(&mut self, edge: E) -> Result<(), GraphError>
pub fn add_edge_with_metadata(&mut self, edge: E) -> Result<(), GraphError>
Push an edge while preserving caller-supplied metadata.
Runs the same self-reference, duplicate, and cycle invariants
as the trait’s Graph::add_edge:
- self-references are rejected always;
- active duplicates (an existing active
source -> target) are rejected always; the duplicate check ignores archived edges so re-adding after archive succeeds; - cycles are rejected when the edge is active, ignored when it is archived (archived edges are not part of the active DAG and don’t constrain new mutations).
Load paths use this to rehydrate stored edges and surface corrupt-DAG state as a hard load failure.
Sourcepub fn descendants(&self, node: E::NodeId) -> Vec<E::NodeId>
pub fn descendants(&self, node: E::NodeId) -> Vec<E::NodeId>
Transitive successors of node (descendants).
Trait Implementations§
Source§impl<E: Edge> Cascadable for DagGraph<E>
impl<E: Edge> Cascadable for DagGraph<E>
Source§fn archive_node(&mut self, node: E::NodeId)
fn archive_node(&mut self, node: E::NodeId)
node (soft delete).Source§fn unarchive_node(&mut self, node: E::NodeId)
fn unarchive_node(&mut self, node: E::NodeId)
node.Source§fn remove_node(&mut self, node: E::NodeId)
fn remove_node(&mut self, node: E::NodeId)
node (hard delete).Source§impl<'de, E> Deserialize<'de> for DagGraph<E>
impl<'de, E> Deserialize<'de> for DagGraph<E>
Source§fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>
Source§impl<E: Edge> EdgeSet for DagGraph<E>
impl<E: Edge> EdgeSet for DagGraph<E>
Source§fn contains(&self, a: E::NodeId, b: E::NodeId) -> bool
fn contains(&self, a: E::NodeId, b: E::NodeId) -> bool
Directed active-only membership: source-to-target ordering
matters. Aligned with Graph::contains_edge.
Source§fn contains_archived(&self, a: E::NodeId, b: E::NodeId) -> bool
fn contains_archived(&self, a: E::NodeId, b: E::NodeId) -> bool
Directed any-state membership including archived edges.
Source§fn active_len(&self) -> usize
fn active_len(&self) -> usize
Source§impl<E: Edge> Graph for DagGraph<E>
impl<E: Edge> Graph for DagGraph<E>
type NodeId = <E as Edge>::NodeId
Source§fn add_edge(&mut self, from: E::NodeId, to: E::NodeId) -> Result<(), GraphError>
fn add_edge(&mut self, from: E::NodeId, to: E::NodeId) -> Result<(), GraphError>
from -> to. Returns GraphError::Cycle /
GraphError::SelfReference when the implementation rejects.Source§fn remove_edge(
&mut self,
from: E::NodeId,
to: E::NodeId,
) -> Result<(), GraphError>
fn remove_edge( &mut self, from: E::NodeId, to: E::NodeId, ) -> Result<(), GraphError>
from -> to. Returns GraphError::EdgeNotFound
if no such edge exists.