Skip to main content

Task

Struct Task 

Source
pub struct Task<Input: NodeArg, Output: NodeArg> { /* private fields */ }
Expand description

A typed task graph that can run sequential, branching, and joining workflows.

Register nodes with Task::register_node or Task::register_node_fn, choose a start node with Task::starts_with, connect nodes with Task::register_transition, and then execute the task with Task::run.

The task value stores runtime state as well as the graph definition, so reuse the same task when you need pause and resume behavior. Clone a task when you want a fresh runtime with the same graph definition.

§Examples

use swiftide_tasks::{NodeError, Task, TaskRunOutcome};

let mut task = Task::<i32, i32>::new();

let start = task.register_node_fn(|input: &i32| -> Result<i32, NodeError> { Ok(*input + 1) });
let finish =
    task.register_node_fn(|input: &i32| -> Result<i32, NodeError> { Ok(*input * 3) });

task.starts_with(start);
task.register_transition(start, move |value| finish.transitions_with(value))?;
task.register_transition(finish, task.transitions_to_finish())?;

assert_eq!(task.run(2).await?, TaskRunOutcome::Completed(9));

Implementations§

Source§

impl<Input: NodeArg + Clone, Output: NodeArg + Clone> Task<Input, Output>

Source

pub fn new() -> Self

Creates a new task with the default runtime behavior.

Source

pub fn with_default_concurrency_model( self, default_concurrency_model: ConcurrencyModel, ) -> Self

Sets the default concurrency model for transitions that do not override it explicitly.

§Examples
use swiftide_tasks::{ConcurrencyModel, Task};

let task = Task::<i32, i32>::new()
    .with_default_concurrency_model(ConcurrencyModel::Parallel);

let _ = task;
Source

pub fn starts_with<T: TaskNode<Input = Input> + Clone + 'static>( &mut self, node_id: NodeId<T>, )

Marks the node where execution should start.

§Examples
use swiftide_tasks::{NodeError, Task};

let mut task = Task::<i32, i32>::new();
let start = task.register_node_fn(|input: &i32| -> Result<i32, NodeError> { Ok(*input) });

task.starts_with(start);
Source

pub fn transitions_to_finish( &self, ) -> impl Fn(Output) -> Transition + Send + Sync + 'static

Returns a typed transition closure that finishes the task with the final output.

Use this from the final node of a task. Fan-out branches cannot finish independently; when multiple branches are conceptually terminal, route them to a join node and finish from that join node instead.

§Examples
use swiftide_tasks::{NodeError, Task, TaskRunOutcome};

let mut task = Task::<i32, i32>::new();
let start = task.register_node_fn(|input: &i32| -> Result<i32, NodeError> { Ok(*input + 1) });

task.starts_with(start);
task.register_transition(start, task.transitions_to_finish())?;

assert_eq!(task.run(2).await?, TaskRunOutcome::Completed(3));
Source

pub async fn run( &mut self, input: impl Into<Input>, ) -> Result<TaskRunOutcome<Output>, TaskError>

Starts the task from its configured start node.

Returns TaskRunOutcome::Completed when the task reaches its finish transition, or TaskRunOutcome::Paused when execution was intentionally paused.

§Errors

Returns an error when the task is already active, when the graph definition is incomplete, or when a node evaluation or transition fails while running the task.

Source

pub fn reset(&mut self)

Resets runtime state while keeping the graph definition and last start input.

After calling reset, use Task::resume to rerun the task from the start node with the most recent input passed to Task::run.

Source

pub async fn resume(&mut self) -> Result<TaskRunOutcome<Output>, TaskError>

Continues a paused or reset task.

§Errors

Returns an error when the task graph is invalid, when there is no paused or reset state to resume, or when a node evaluation or transition fails while continuing execution.

Source

pub fn current_nodes<T: TaskNode + 'static>(&self) -> CurrentNodes<'_, T>

Returns the current paused or runnable nodes that have the requested type.

Paused branches take precedence over runnable branches. Runnable branches are only returned when no paused branches exist.

Source

pub fn register_node<T>(&mut self, node: T) -> NodeId<T>
where T: TaskNode + 'static + Clone,

Registers a node in the task graph and returns its typed identifier.

§Examples
use async_trait::async_trait;
use swiftide_tasks::{DynNodeId, NodeError, Task, TaskNode};

#[derive(Clone)]
struct Increment;

#[async_trait]
impl TaskNode for Increment {
    type Input = i32;
    type Output = i32;
    type Error = NodeError;

    async fn evaluate(
        &self,
        _node_id: &DynNodeId<Self>,
        input: &Self::Input,
    ) -> Result<Self::Output, Self::Error> {
        Ok(*input + 1)
    }
}

let mut task = Task::<i32, i32>::new();
let start = task.register_node(Increment);

let _ = start;
Source

pub fn register_node_fn<F, I, O, E>( &mut self, f: F, ) -> NodeId<SyncFn<F, I, O, E>>
where F: Fn(&I) -> Result<O, E> + Send + Sync + Clone + 'static, I: NodeArg + Clone, O: NodeArg + Clone, E: Error + Send + Sync + 'static,

Registers a synchronous closure as a task node.

This is the convenience entry point for examples, tests, and small bits of task glue. For reusable domain logic, prefer implementing TaskNode directly and calling Task::register_node.

§Examples
use swiftide_tasks::{NodeError, Task};

let mut task = Task::<i32, i32>::new();
let double = task.register_node_fn(|input: &i32| -> Result<i32, NodeError> {
    Ok(*input * 2)
});

let _ = double;
Source

pub fn register_node_async_fn<F, I, O, E>( &mut self, f: F, ) -> NodeId<AsyncFn<F, I, O, E>>
where F: for<'a> Fn(&'a I) -> Pin<Box<dyn Future<Output = Result<O, E>> + Send + 'a>> + Send + Sync + Clone + 'static, I: NodeArg + Clone, O: NodeArg + Clone, E: Error + Send + Sync + 'static,

Registers an asynchronous closure as a task node.

§Examples
use swiftide_tasks::{NodeError, Task};

let mut task = Task::<i32, i32>::new();
let double = task.register_node_async_fn(|input: &i32| {
    Box::pin(async move { Ok::<i32, NodeError>(*input * 2) })
});

let _ = double;
Source

pub fn register_transition<From, R>( &mut self, from: NodeId<From>, transition: R, ) -> Result<(), TaskError>
where From: TaskNode + 'static + ?Sized, R: RegisterTransition<From>,

Registers how execution should continue after from completes.

The transition may be:

§Examples
use swiftide_tasks::{NodeError, Task};

let mut task = Task::<i32, i32>::new();
let start = task.register_node_fn(|input: &i32| -> Result<i32, NodeError> { Ok(*input + 1) });
let finish = task.register_node_fn(|input: &i32| -> Result<i32, NodeError> { Ok(*input * 2) });

task.starts_with(start);
task.register_transition(start, move |value| finish.transitions_with(value))?;
§Errors

Returns an error when from is unknown, when the node already has a registered transition, or when the transition type does not match the registered node type.

Source

pub fn register_transition_async<From, R>( &mut self, from: NodeId<From>, transition: R, ) -> Result<(), TaskError>
where From: TaskNode + 'static + ?Sized, R: RegisterTransitionAsync<From>,

Registers an asynchronous transition or async join payload mapping for from.

§Examples
use swiftide_tasks::{NodeError, Task};

let mut task = Task::<i32, i32>::new();
let start = task.register_node_fn(|input: &i32| -> Result<i32, NodeError> { Ok(*input + 1) });
let finish = task.register_node_fn(|input: &i32| -> Result<i32, NodeError> { Ok(*input * 2) });

task.starts_with(start);
task.register_transition_async(start, move |value| async move { finish.transitions_with(value) })?;
§Errors

Returns an error when from is unknown, when the node already has a registered transition, or when the transition type does not match the registered node type.

Trait Implementations§

Source§

impl<Input: NodeArg, Output: NodeArg> Clone for Task<Input, Output>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<Input: Debug + NodeArg, Output: Debug + NodeArg> Debug for Task<Input, Output>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<Input: NodeArg + Clone, Output: NodeArg + Clone> Default for Task<Input, Output>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<Input, Output> !RefUnwindSafe for Task<Input, Output>

§

impl<Input, Output> !UnwindSafe for Task<Input, Output>

§

impl<Input, Output> Forget for Task<Input, Output>

§

impl<Input, Output> Freeze for Task<Input, Output>

§

impl<Input, Output> Send for Task<Input, Output>

§

impl<Input, Output> Sync for Task<Input, Output>

§

impl<Input, Output> Unpin for Task<Input, Output>

§

impl<Input, Output> UnsafeUnpin for Task<Input, Output>

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> NodeArg for T
where T: Send + Sync + Debug + 'static + Clone,

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more