Skip to main content

typed_eventbus/
envelop.rs

1use jiff::Timestamp;
2use serde::{Deserialize, Serialize};
3use std::error::Error;
4use std::sync::Arc;
5use uuid::Uuid;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub enum Identifier {
9    Uuid(Uuid),
10    Tag(String),
11}
12
13impl From<Uuid> for Identifier {
14    fn from(value: Uuid) -> Self {
15        Identifier::Uuid(value)
16    }
17}
18
19impl From<&str> for Identifier{
20    fn from(value: &str) ->Identifier{
21        if let Ok(v) = value.parse(){
22            return v
23        }
24        Identifier::Tag(value.to_string())
25    }
26}
27
28use std::str::FromStr;
29
30impl FromStr for Identifier {
31    type Err = String;
32
33    fn from_str(s: &str) -> Result<Self, Self::Err> {
34        // Try parsing as UUID first
35        if let Ok(uuid) = Uuid::parse_str(s) {
36            return Ok(Identifier::Uuid(uuid));
37        }
38        // Otherwise treat as Tag
39        Ok(Identifier::Tag(s.to_string()))
40    }
41}
42
43use crate::{EventStream, Publishable};
44
45#[derive(Debug, Clone, Serialize, Deserialize)]
46pub struct EventMetaData {
47    pub event_id: Uuid,
48    pub event_version: String,
49    pub occurred_at: Timestamp,
50    pub producer: Option<String>,
51    pub correlation_id: Option<Uuid>,
52    pub trace_id: Option<Uuid>,
53    pub user_id: Option<Uuid>,
54    pub audience: Vec<Identifier>,
55    pub session_id: Option<Uuid>,
56}
57
58impl EventMetaData {
59    pub fn new() -> Self {
60        Self {
61            event_id: Uuid::new_v4(),
62            event_version: "v1".to_string(),
63            occurred_at: Timestamp::now(),
64            producer: None,
65            correlation_id: None,
66            trace_id: None,
67            user_id: None,
68            session_id: None,
69            audience: Vec::new(),
70        }
71    }
72
73    pub fn with_producer(mut self, producer: impl Into<String>) -> Self {
74        self.producer = Some(producer.into());
75        self
76    }
77
78    pub fn with_correlation_id(mut self, id: Uuid) -> Self {
79        self.correlation_id = Some(id);
80        self
81    }
82
83    pub fn with_trace_id(mut self, id: Uuid) -> Self {
84        self.trace_id = Some(id);
85        self
86    }
87
88    pub fn with_user_id(mut self, id: Uuid) -> Self {
89        self.user_id = Some(id);
90        self
91    }
92
93    pub fn with_session_id(mut self, id: Uuid) -> Self {
94        self.session_id = Some(id);
95        self
96    }
97    pub fn with_audience(mut self, aud: Vec<Identifier>) -> Self {
98        self.audience = aud;
99        self
100    }
101}
102
103#[derive(Serialize, Deserialize)]
104pub struct Event<T> {
105    pub metadata: EventMetaData,
106    pub payload: T,
107}
108
109impl<T: Publishable + Sync> Event<T> {
110    pub fn new(payload: T) -> Self {
111        let metadata = EventMetaData::new();
112        Self { metadata, payload }
113    }
114    pub async fn publish(
115        &self,
116        es: Arc<dyn EventStream>,
117    ) -> Result<(), Box<dyn Error + Send + Sync>> {
118        match es
119            .publish(
120                T::SUBJECT.to_string(),
121                serde_json::to_string(self).unwrap().into_bytes(),
122            )
123            .await
124        {
125            Ok(_) => (),
126            Err(e) => eprintln!("Error in publishing event: {e}"),
127        };
128        Ok(())
129    }
130
131    pub fn with_producer(mut self, producer: impl Into<String>) -> Self {
132        self.metadata = self.metadata.with_producer(producer);
133        self
134    }
135
136    pub fn with_correlation_id(mut self, id: Uuid) -> Self {
137        self.metadata = self.metadata.with_correlation_id(id);
138        self
139    }
140
141    pub fn with_trace_id(mut self, id: Uuid) -> Self {
142        self.metadata = self.metadata.with_trace_id(id);
143        self
144    }
145
146    pub fn with_user_id(mut self, id: Uuid) -> Self {
147        self.metadata = self.metadata.with_user_id(id);
148        self
149    }
150
151    pub fn with_session_id(mut self, id: Uuid) -> Self {
152        self.metadata = self.metadata.with_session_id(id);
153        self
154    }
155    pub fn with_audience<U>(mut self, aud: Vec<U>) -> Self
156    where
157        U: Into<Identifier>,
158    {
159        self.metadata = self
160            .metadata
161            .with_audience(aud.into_iter().map(Into::into).collect());
162        self
163    }
164    pub fn add_audience<U>(mut self, aud: U) -> Self
165    where
166        U: Into<Identifier>,
167    {
168        self.metadata.audience.push(aud.into());
169        self
170    }
171}