forge_core/workflow/
events.rs1use std::future::Future;
2
3use serde::Serialize;
4use uuid::Uuid;
5
6use crate::ForgeError;
7
8pub trait WorkflowEventSender: Send + Sync {
10 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#[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
36pub 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)]
42#[allow(clippy::unwrap_used, clippy::indexing_slicing)]
43mod tests {
44 use super::*;
45
46 #[tokio::test]
47 async fn test_noop_sender() {
48 let sender = NoOpEventSender;
49 let result = sender.send_event("test", "123", None).await;
50 assert!(result.is_err());
51 }
52
53 #[test]
54 fn test_serialize_payload() {
55 #[derive(Serialize)]
56 struct TestPayload {
57 value: i32,
58 }
59
60 let payload = TestPayload { value: 42 };
61 let result = serialize_payload(&payload);
62 assert!(result.is_ok());
63 assert_eq!(result.unwrap(), serde_json::json!({"value": 42}));
64 }
65}