Skip to main content

forge_core/workflow/
events.rs

1use std::future::Future;
2
3use serde::Serialize;
4use uuid::Uuid;
5
6use crate::ForgeError;
7
8/// Trait for sending workflow events.
9pub trait WorkflowEventSender: Send + Sync {
10    /// Send an event to a workflow.
11    fn send_event(
12        &self,
13        event_name: &str,
14        correlation_id: &str,
15        payload: Option<serde_json::Value>,
16    ) -> impl Future<Output = Result<Uuid, ForgeError>> + Send;
17}
18
19/// No-op event sender for contexts without event sending capability.
20#[derive(Debug, Clone, Copy)]
21pub struct NoOpEventSender;
22
23impl WorkflowEventSender for NoOpEventSender {
24    async fn send_event(
25        &self,
26        _event_name: &str,
27        _correlation_id: &str,
28        _payload: Option<serde_json::Value>,
29    ) -> Result<Uuid, ForgeError> {
30        Err(ForgeError::InvalidState(
31            "Event sending not available in this context".into(),
32        ))
33    }
34}
35
36/// Helper function to serialize a payload.
37pub fn serialize_payload<T: Serialize>(payload: &T) -> Result<serde_json::Value, ForgeError> {
38    serde_json::to_value(payload).map_err(|e| ForgeError::Serialization(e.to_string()))
39}
40
41#[cfg(test)]
42mod tests {
43    use super::*;
44
45    #[tokio::test]
46    async fn test_noop_sender() {
47        let sender = NoOpEventSender;
48        let result = sender.send_event("test", "123", None).await;
49        assert!(result.is_err());
50    }
51
52    #[test]
53    fn test_serialize_payload() {
54        #[derive(Serialize)]
55        struct TestPayload {
56            value: i32,
57        }
58
59        let payload = TestPayload { value: 42 };
60        let result = serialize_payload(&payload);
61        assert!(result.is_ok());
62        assert_eq!(result.unwrap(), serde_json::json!({"value": 42}));
63    }
64}