cuenv_task_graph/resolver.rs
1//! Task resolution abstractions for group expansion.
2//!
3//! This module provides the [`TaskResolution`] enum and [`TaskResolver`] trait
4//! that enable unified handling of single tasks and task groups (sequential/parallel).
5
6use crate::TaskNodeData;
7
8/// How a task name resolves - single task or group.
9///
10/// This enum represents the three ways a task name can resolve:
11/// - A single leaf task (no children)
12/// - A sequential group (children run in order)
13/// - A parallel group (children run concurrently)
14#[derive(Debug, Clone)]
15pub enum TaskResolution<T: TaskNodeData> {
16 /// A single leaf task with its data.
17 Single(T),
18
19 /// Sequential group - tasks run in order (implicit deps between them).
20 ///
21 /// Children are named like `"build[0]"`, `"build[1]"` for a group named `"build"`.
22 Sequential {
23 /// Child task names in execution order.
24 children: Vec<String>,
25 },
26
27 /// Parallel group - tasks can run concurrently.
28 ///
29 /// Children are named like `"build.frontend"`, `"build.backend"` for a group named `"build"`.
30 Parallel {
31 /// Child task names (no particular order).
32 children: Vec<String>,
33 /// Group-level dependencies applied to all children.
34 depends_on: Vec<String>,
35 },
36}
37
38/// Trait for resolving task names to their definitions.
39///
40/// Implement this trait to provide task lookup and group expansion
41/// for use with [`TaskGraph::build_for_task_with_resolver`].
42///
43/// # Example
44///
45/// ```ignore
46/// impl TaskResolver<Task> for Tasks {
47/// fn resolve(&self, name: &str) -> Option<TaskResolution<Task>> {
48/// let definition = self.get(name)?;
49/// match definition {
50/// TaskDefinition::Single(task) => Some(TaskResolution::Single(task.clone())),
51/// TaskDefinition::Group(TaskGroup::Sequential(tasks)) => {
52/// let children = (0..tasks.len())
53/// .map(|i| format!("{}[{}]", name, i))
54/// .collect();
55/// Some(TaskResolution::Sequential { children })
56/// }
57/// // ... parallel handling
58/// }
59/// }
60/// }
61/// ```
62pub trait TaskResolver<T: TaskNodeData> {
63 /// Resolve a task name to its definition (single or group).
64 ///
65 /// Returns `None` if the task doesn't exist.
66 fn resolve(&self, name: &str) -> Option<TaskResolution<T>>;
67}