Skip to main content

alien_core/events/
handle.rs

1use crate::events::{AlienEvent, EventBus, EventState};
2use crate::Result;
3use alien_error::{AlienError, AlienErrorData};
4use serde::{Deserialize, Serialize};
5#[cfg(feature = "openapi")]
6use utoipa::ToSchema;
7
8/// Handle to an emitted event that allows updating it
9#[derive(Debug, Clone, Serialize, Deserialize)]
10#[cfg_attr(feature = "openapi", derive(ToSchema))]
11pub struct EventHandle {
12    /// Unique identifier for the event
13    pub id: String,
14    /// Parent event ID if this is a child event
15    pub parent_id: Option<String>,
16    /// Whether this is a no-op handle (when no event bus is available)
17    #[serde(skip)]
18    pub is_noop: bool,
19}
20
21impl EventHandle {
22    /// Create a new event handle
23    pub fn new(id: String, parent_id: Option<String>) -> Self {
24        Self {
25            id,
26            parent_id,
27            is_noop: false,
28        }
29    }
30
31    /// Create a no-op event handle (used when no event bus is available)
32    pub fn noop() -> Self {
33        Self {
34            id: "noop".to_string(),
35            parent_id: None,
36            is_noop: true,
37        }
38    }
39
40    /// Update the event with new data
41    pub async fn update(&self, event: AlienEvent) -> Result<()> {
42        if self.is_noop {
43            return Ok(());
44        }
45        EventBus::update(&self.id, event).await
46    }
47
48    /// Mark the event as completed successfully
49    pub async fn complete(&self) -> Result<()> {
50        if self.is_noop {
51            return Ok(());
52        }
53        EventBus::update_state(&self.id, EventState::Success).await
54    }
55
56    /// Mark the event as failed with an error
57    pub async fn fail<E>(&self, error: AlienError<E>) -> Result<()>
58    where
59        E: AlienErrorData + Clone + std::fmt::Debug + Serialize,
60    {
61        if self.is_noop {
62            return Ok(());
63        }
64        EventBus::update_state(
65            &self.id,
66            EventState::Failed {
67                error: Some(error.into_generic()),
68            },
69        )
70        .await
71    }
72
73    /// Create a child scope with this handle as parent
74    pub async fn as_parent<F, Fut, T>(&self, f: F) -> T
75    where
76        F: FnOnce(&EventHandle) -> Fut,
77        Fut: std::future::Future<Output = T>,
78    {
79        if self.is_noop {
80            return f(self).await;
81        }
82        let parent_id = self.id.clone();
83        EventBus::with_parent(Some(parent_id), f).await
84    }
85}