Skip to main content

dataflow_rs/engine/
task.rs

1//! # Task Module
2//!
3//! This module defines the `Task` structure, which represents a single
4//! processing unit within a workflow. Tasks are the fundamental building
5//! blocks of data processing pipelines.
6
7use crate::engine::functions::FunctionConfig;
8use serde::Deserialize;
9use serde_json::Value;
10
11/// A single processing unit within a workflow (also known as an Action in rules-engine terminology).
12///
13/// Tasks execute functions with optional conditions and error handling.
14/// They are processed sequentially within a workflow, allowing later tasks
15/// to depend on results from earlier ones.
16///
17/// # Example JSON Definition
18///
19/// ```json
20/// {
21///     "id": "validate_user",
22///     "name": "Validate User Data",
23///     "description": "Ensures user data meets requirements",
24///     "condition": {">=": [{"var": "data.order.total"}, 1000]},
25///     "function": {
26///         "name": "validation",
27///         "input": { "rules": [...] }
28///     },
29///     "continue_on_error": false
30/// }
31/// ```
32#[derive(Clone, Debug, Deserialize)]
33pub struct Task {
34    /// Unique identifier for the task within the workflow.
35    pub id: String,
36
37    /// Human-readable name for the task.
38    pub name: String,
39
40    /// Optional description explaining what the task does.
41    pub description: Option<String>,
42
43    /// JSONLogic condition that determines if the task should execute.
44    /// Conditions can access any context field (`data`, `metadata`, `temp_data`).
45    /// Defaults to `true` (always execute).
46    #[serde(default = "default_condition")]
47    pub condition: Value,
48
49    /// Index into the compiled logic cache for this task's condition.
50    /// Set during workflow compilation; not serialized.
51    #[serde(skip)]
52    pub condition_index: Option<usize>,
53
54    /// The function configuration specifying what operation to perform.
55    /// Can be a built-in function (map, validation) or a custom function.
56    pub function: FunctionConfig,
57
58    /// Whether to continue workflow execution if this task fails.
59    /// When `true`, errors are recorded but don't stop the workflow.
60    /// Defaults to `false`.
61    #[serde(default)]
62    pub continue_on_error: bool,
63}
64
65impl Task {
66    /// Create a task (action) with default settings.
67    ///
68    /// This is a convenience constructor for the IFTTT-style rules engine pattern,
69    /// creating an action that always executes (condition defaults to `true`).
70    ///
71    /// # Arguments
72    /// * `id` - Unique identifier for the action
73    /// * `name` - Human-readable name
74    /// * `function` - The function configuration to execute
75    pub fn action(id: &str, name: &str, function: FunctionConfig) -> Self {
76        Task {
77            id: id.to_string(),
78            name: name.to_string(),
79            description: None,
80            condition: Value::Bool(true),
81            condition_index: None,
82            function,
83            continue_on_error: false,
84        }
85    }
86}
87
88/// Returns the default condition value (always true).
89fn default_condition() -> Value {
90    Value::Bool(true)
91}