bijux-dag-core 0.4.1

Deterministic DAG kernel for graph parsing, validation, canonicalization, planning, and identity.
Documentation
use crate::contract::{normalize_graph_with_defaults, GraphContract};
use crate::expansion::expand_graph;
use crate::node::{derive_interface, NodeTypeRegistry, TypedNode};
use crate::resources::GraphDefaults;
use crate::{
    parse_graph_strict, Graph, GraphError, ValidationDiagnostic, CANONICALIZATION_CONTRACT_VERSION,
};
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DagCompilePlanHints {
    pub deterministic_topology_order: Vec<String>,
    pub typed_nodes: Vec<TypedNode>,
    pub canonicalization_contract_version: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DagCompileResult {
    pub normalized_graph: Graph,
    pub diagnostics: Vec<ValidationDiagnostic>,
    pub graph_fingerprint: String,
    pub plan_hints: DagCompilePlanHints,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum CompatibilityDecision {
    AcceptExact,
    RejectVersion,
}

pub fn negotiate_spec_version(version: &str) -> CompatibilityDecision {
    if version == crate::SPEC_VERSION || version == "0.1" || version == "v0.1" {
        CompatibilityDecision::AcceptExact
    } else {
        CompatibilityDecision::RejectVersion
    }
}

pub fn compile_graph(graph: &Graph) -> Result<DagCompileResult, GraphError> {
    compile_graph_with_defaults(graph, &GraphDefaults::default())
}

pub fn compile_graph_with_defaults(
    graph: &Graph,
    defaults: &GraphDefaults,
) -> Result<DagCompileResult, GraphError> {
    let expanded_graph = expand_graph(graph).map_err(|_| GraphError::ValidationFailed)?;
    let normalized_graph = normalize_graph_with_defaults(&expanded_graph, defaults).canonicalize();
    let diagnostics = normalized_graph.validate_with_warnings();
    let graph_fingerprint = normalized_graph.graph_fingerprint()?;
    let deterministic_topology_order = normalized_graph.topo_order()?;
    let typed_nodes = normalized_graph
        .nodes
        .iter()
        .cloned()
        .map(|node| TypedNode { interface: derive_interface(&node), node })
        .collect();
    let registry = NodeTypeRegistry::default_registry();
    registry
        .validate_node_kinds(&normalized_graph.nodes)
        .map_err(|_| GraphError::ValidationFailed)?;

    Ok(DagCompileResult {
        normalized_graph,
        diagnostics,
        graph_fingerprint,
        plan_hints: DagCompilePlanHints {
            deterministic_topology_order,
            typed_nodes,
            canonicalization_contract_version: CANONICALIZATION_CONTRACT_VERSION.to_string(),
        },
    })
}

pub fn compile_graph_contract(contract: &GraphContract) -> Result<DagCompileResult, GraphError> {
    compile_graph_with_defaults(&contract.graph, &contract.defaults)
}

pub fn compile_graph_strict(input: &str) -> Result<DagCompileResult, GraphError> {
    let graph = parse_graph_strict(input)?;
    compile_graph(&graph)
}