Skip to main content

rustvello_proto/trigger/
definition.rs

1//! Trigger definition DTO and valid condition types.
2
3use serde::{Deserialize, Serialize};
4use sha2::{Digest, Sha256};
5
6use crate::identifiers::TaskId;
7
8use super::context::ConditionContext;
9use super::{ConditionId, TriggerDefinitionId, TriggerLogic};
10
11/// A trigger definition links conditions to a target task.
12///
13/// When the conditions are satisfied (according to `logic`), the target
14/// task is invoked with the given `argument_template`.
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct TriggerDefinitionDTO {
17    pub trigger_id: TriggerDefinitionId,
18    pub task_id: TaskId,
19    pub condition_ids: Vec<ConditionId>,
20    pub logic: TriggerLogic,
21    /// Optional static arguments to pass to the triggered task.
22    pub argument_template: Option<serde_json::Value>,
23}
24
25impl TriggerDefinitionDTO {
26    /// Compute a deterministic trigger ID from (task_id + sorted conditions + logic).
27    pub fn compute_trigger_id(
28        task_id: &TaskId,
29        condition_ids: &[ConditionId],
30        logic: TriggerLogic,
31    ) -> TriggerDefinitionId {
32        let mut hasher = Sha256::new();
33        hasher.update(task_id.to_string().as_bytes());
34        hasher.update(b"|");
35        let mut sorted: Vec<&str> = condition_ids.iter().map(ConditionId::as_str).collect();
36        sorted.sort();
37        for id in &sorted {
38            hasher.update(id.as_bytes());
39            hasher.update(b",");
40        }
41        hasher.update(b"|");
42        hasher.update(logic.to_string().as_bytes());
43        TriggerDefinitionId(format!("{:x}", hasher.finalize()))
44    }
45}
46
47/// A condition that has been evaluated and found to be satisfied.
48///
49/// Stored in the trigger store until the trigger definition is evaluated.
50#[derive(Debug, Clone, Serialize, Deserialize)]
51pub struct ValidCondition {
52    /// Unique ID: "valid_{condition_id}_{context_id}"
53    pub valid_condition_id: String,
54    pub condition_id: ConditionId,
55    pub context: ConditionContext,
56}
57
58impl ValidCondition {
59    pub fn new(condition_id: ConditionId, context: ConditionContext) -> Self {
60        let context_id = context.context_id();
61        let valid_condition_id = format!("valid_{}_{}", condition_id.0, context_id);
62        Self {
63            valid_condition_id,
64            condition_id,
65            context,
66        }
67    }
68}