Skip to main content

cuenv_task_graph/
error.rs

1//! Error types for task graph operations.
2
3use std::fmt;
4
5/// Result type for task graph operations.
6pub type Result<T> = std::result::Result<T, Error>;
7
8/// Errors that can occur during task graph operations.
9#[derive(Debug, Clone)]
10pub enum Error {
11    /// A dependency cycle was detected in the graph.
12    CycleDetected {
13        /// Human-readable description of the cycle.
14        message: String,
15    },
16
17    /// A task depends on another task that doesn't exist.
18    MissingDependency {
19        /// The task that has the missing dependency.
20        task: String,
21        /// The name of the missing dependency.
22        dependency: String,
23    },
24
25    /// Multiple missing dependencies were found.
26    MissingDependencies {
27        /// List of (task, missing_dependency) pairs.
28        missing: Vec<(String, String)>,
29    },
30
31    /// Failed to perform topological sort.
32    TopologicalSortFailed {
33        /// Reason for the failure.
34        reason: String,
35    },
36
37    /// A node name is used by different kinds (e.g., task and image both named "api").
38    DuplicateNodeName {
39        /// The colliding name.
40        name: String,
41        /// The kind of the existing node.
42        existing_kind: String,
43        /// The kind of the new node being added.
44        new_kind: String,
45    },
46}
47
48impl fmt::Display for Error {
49    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50        match self {
51            Self::CycleDetected { message } => {
52                write!(f, "Cycle detected in task graph: {message}")
53            }
54            Self::MissingDependency { task, dependency } => {
55                write!(f, "Task '{task}' depends on missing task '{dependency}'")
56            }
57            Self::MissingDependencies { missing } => {
58                let list = missing
59                    .iter()
60                    .map(|(task, dep)| format!("Task '{task}' depends on missing task '{dep}'"))
61                    .collect::<Vec<_>>()
62                    .join(", ");
63                write!(f, "Missing dependencies: {list}")
64            }
65            Self::TopologicalSortFailed { reason } => {
66                write!(f, "Failed to sort tasks topologically: {reason}")
67            }
68            Self::DuplicateNodeName {
69                name,
70                existing_kind,
71                new_kind,
72            } => {
73                write!(
74                    f,
75                    "Node name '{name}' is already used by a {existing_kind}; cannot add as {new_kind}"
76                )
77            }
78        }
79    }
80}
81
82impl std::error::Error for Error {}