TaskBuilder

Struct TaskBuilder 

Source
pub struct TaskBuilder<'a, Tk: Task, Deps> { /* private fields */ }
Expand description

Node builder that tracks dependency completion via type state.

A TaskBuilder<Tk, Deps> is returned from DagRunner::add_task and uses the type-state pattern to ensure dependencies are wired correctly at compile time:

  • TaskBuilder<Tk, Pending>: No dependencies specified yet
  • TaskBuilder<Tk, Tk::Input>: Dependencies complete; acts as a TaskHandle<Tk::Output>

§Examples

// Using tuple struct for simple constants
struct Constant(i32);

#[task]
impl Constant {
    async fn run(&mut self) -> i32 { self.0 }
}

// Task with state constructed via ::new()
struct Multiplier { factor: i32 }

impl Multiplier {
    fn new(factor: i32) -> Self { Self { factor } }
}

#[task]
impl Multiplier {
    async fn run(&mut self, x: &i32) -> i32 { x * self.factor }
}

let mut dag = DagRunner::new();

// Construct with initial value (tuple struct)
let a = dag.add_task(Constant(10));
// a is TaskBuilder<_, Pending> since no dependencies needed (Input = ())

// Construct with ::new() pattern
let b = dag.add_task(Multiplier::new(2));
// b is TaskBuilder<_, Pending> until we call depends_on()

let b = b.depends_on(&a);
// Now b is a TaskHandle<i32>

dag.run(|fut| { tokio::spawn(fut); }).await.unwrap();
assert_eq!(dag.get(&b).unwrap(), 20);

Implementations§

Source§

impl<'a, Tk: Task, Deps> TaskBuilder<'a, Tk, Deps>

Source

pub fn depends_on<D>(self, deps: D) -> TaskHandle<Tk::Output>
where D: DepsTuple<Tk::Input>,

Provide all dependencies exactly once as a tuple.

The dependencies must match the task’s Input type exactly:

  • Input = (): Do not call depends_on
  • Input = T: Pass &TaskHandle or (&TaskHandle,)
  • Input = (A, B, ...): Pass (&TaskHandle<A>, &TaskHandle<B>, ...)

The order of dependencies in the tuple must match the order in Input.

§Examples
// Tuple struct
struct Value(i32);

#[task]
impl Value {
    async fn run(&mut self) -> i32 { self.0 }
}

// Tuple struct with multiplier
struct Scale(i32);

#[task]
impl Scale {
    async fn run(&mut self, x: &i32) -> i32 { x * self.0 }
}

// Unit struct
struct Add;

#[task]
impl Add {
    async fn run(&mut self, a: &i32, b: &i32) -> i32 { a + b }
}

let dag = DagRunner::new();

let x = dag.add_task(Value(2));
let y = dag.add_task(Value(3));

// Single dependency
let double = dag.add_task(Scale(2)).depends_on(&x);

// Multiple dependencies: tuple form
let sum = dag.add_task(Add).depends_on((&x, &y));

dag.run(|fut| { tokio::spawn(fut); }).await.unwrap();

Trait Implementations§

Source§

impl<'a, Tk: Task, Deps> From<&TaskBuilder<'a, Tk, Deps>> for TaskHandle<Tk::Output>
where Tk::Input: IsUnitType,

Source§

fn from(node: &TaskBuilder<'a, Tk, Deps>) -> Self

Converts to this type from the input type.
Source§

impl<'a, Tk: Task, Deps> From<TaskBuilder<'a, Tk, Deps>> for TaskHandle<Tk::Output>
where Tk::Input: IsUnitType,

Source§

fn from(node: TaskBuilder<'a, Tk, Deps>) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl<'a, Tk, Deps> Freeze for TaskBuilder<'a, Tk, Deps>

§

impl<'a, Tk, Deps> !RefUnwindSafe for TaskBuilder<'a, Tk, Deps>

§

impl<'a, Tk, Deps> Send for TaskBuilder<'a, Tk, Deps>
where Deps: Send,

§

impl<'a, Tk, Deps> Sync for TaskBuilder<'a, Tk, Deps>
where Tk: Sync, Deps: Sync,

§

impl<'a, Tk, Deps> Unpin for TaskBuilder<'a, Tk, Deps>
where Tk: Unpin, Deps: Unpin,

§

impl<'a, Tk, Deps> !UnwindSafe for TaskBuilder<'a, Tk, Deps>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.