//! Hand trigger definitions use serde::{Deserialize, Serialize}; use serde_json::Value; use chrono::{DateTime, Utc}; /// Trigger configuration #[derive(Debug, Clone, Serialize, Deserialize)] pub struct TriggerConfig { /// Unique trigger identifier pub id: String, /// Human-readable name pub name: String, /// Hand ID to trigger pub hand_id: String, /// Trigger type pub trigger_type: TriggerType, /// Whether the trigger is enabled #[serde(default = "default_enabled")] pub enabled: bool, /// Maximum executions per hour (rate limiting) #[serde(default = "default_max_executions")] pub max_executions_per_hour: u32, } fn default_enabled() -> bool { true } fn default_max_executions() -> u32 { 10 } /// Trigger type #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(tag = "type", rename_all = "snake_case")] pub enum TriggerType { /// Time-based trigger Schedule { /// Cron expression cron: String, }, /// Event-based trigger Event { /// Event pattern to match pattern: String, }, /// Webhook trigger Webhook { /// Webhook path path: String, /// Secret for verification secret: Option, }, /// Message pattern trigger MessagePattern { /// Regex pattern pattern: String, }, /// File system trigger FileSystem { /// Path to watch path: String, /// Events to watch for events: Vec, }, /// Manual trigger only Manual, } /// File system event types #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub enum FileEvent { Created, Modified, Deleted, Any, } /// Trigger state #[derive(Debug, Clone, Serialize, Deserialize)] pub struct TriggerState { /// Trigger ID pub trigger_id: String, /// Last execution time pub last_execution: Option>, /// Execution count in current hour pub execution_count: u32, /// Last execution result pub last_result: Option, /// Whether the trigger is active pub is_active: bool, } impl TriggerState { pub fn new(trigger_id: impl Into) -> Self { Self { trigger_id: trigger_id.into(), last_execution: None, execution_count: 0, last_result: None, is_active: true, } } } /// Trigger execution result #[derive(Debug, Clone, Serialize, Deserialize)] pub struct TriggerResult { /// Execution timestamp pub timestamp: DateTime, /// Whether execution succeeded pub success: bool, /// Output from hand execution pub output: Option, /// Error message if failed pub error: Option, /// Input that triggered execution pub trigger_input: Value, } impl TriggerResult { pub fn success(trigger_input: Value, output: Value) -> Self { Self { timestamp: Utc::now(), success: true, output: Some(output), error: None, trigger_input, } } pub fn error(trigger_input: Value, error: impl Into) -> Self { Self { timestamp: Utc::now(), success: false, output: None, error: Some(error.into()), trigger_input, } } } /// Trigger trait pub trait Trigger: Send + Sync { /// Get trigger configuration fn config(&self) -> &TriggerConfig; /// Check if trigger should fire fn should_fire(&self, input: &Value) -> bool; /// Update trigger state fn update_state(&mut self, result: TriggerResult); }