1use crate::{Topic, Partition, Offset};
7use derive_more::{Deref, DerefMut, From, Into};
8use serde::{Deserialize, Serialize};
9use std::time::{SystemTime, UNIX_EPOCH};
10use uuid::Uuid;
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Deref, DerefMut, From, Into)]
24pub struct EventId(pub Uuid);
25
26impl EventId {
27 pub fn new() -> Self {
29 Self(Uuid::new_v4())
30 }
31
32 pub fn from_uuid(uuid: Uuid) -> Self {
34 Self(uuid)
35 }
36}
37
38impl Default for EventId {
39 fn default() -> Self {
40 Self::new()
41 }
42}
43
44impl std::fmt::Display for EventId {
45 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46 write!(f, "{}", self.0)
47 }
48}
49
50#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Deref, DerefMut, From, Into)]
60pub struct EventData(pub Vec<u8>);
61
62impl EventData {
63 pub fn new(data: Vec<u8>) -> Self {
65 Self(data)
66 }
67
68 pub fn from_bytes(bytes: impl Into<Vec<u8>>) -> Self {
70 Self(bytes.into())
71 }
72
73 pub fn from_json(json: &str) -> Self {
75 Self(json.as_bytes().to_vec())
76 }
77
78 pub fn len(&self) -> usize {
80 self.0.len()
81 }
82
83 pub fn is_empty(&self) -> bool {
85 self.0.is_empty()
86 }
87
88 pub fn as_bytes(&self) -> &[u8] {
90 &self.0
91 }
92
93 pub fn as_str(&self) -> Option<&str> {
95 std::str::from_utf8(&self.0).ok()
96 }
97
98 pub fn to_json(&self) -> String {
106 match std::str::from_utf8(&self.0) {
107 Ok(s) => s.to_string(),
108 Err(_) => {
109 use base64::Engine;
111 base64::engine::general_purpose::STANDARD.encode(&self.0)
112 }
113 }
114 }
115
116 pub fn to_json_value(&self) -> Result<serde_json::Value, serde_json::Error> {
121 match std::str::from_utf8(&self.0) {
122 Ok(s) => serde_json::from_str(s),
123 Err(_) => {
124 use base64::Engine;
126 let base64_str = base64::engine::general_purpose::STANDARD.encode(&self.0);
127 Ok(serde_json::Value::String(base64_str))
128 }
129 }
130 }
131
132 pub fn from_json_validated(json: &str) -> Result<Self, serde_json::Error> {
140 let _: serde_json::Value = serde_json::from_str(json)?;
142 Ok(Self::from_json(json))
143 }
144
145 pub fn to_text(&self) -> String {
150 match std::str::from_utf8(&self.0) {
151 Ok(s) => s.to_string(),
152 Err(_) => format!("<binary data: {} bytes>", self.0.len()),
153 }
154 }
155}
156
157#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Deref, DerefMut, From, Into)]
161pub struct Timestamp(pub u64);
162
163impl Timestamp {
164 pub fn now() -> Self {
166 let duration = SystemTime::now()
167 .duration_since(UNIX_EPOCH)
168 .unwrap_or_default();
169 Self(duration.as_millis() as u64)
170 }
171
172 pub fn from_millis(millis: u64) -> Self {
174 Self(millis)
175 }
176
177 pub fn as_millis(&self) -> u64 {
179 self.0
180 }
181}
182
183impl Default for Timestamp {
184 fn default() -> Self {
185 Self::now()
186 }
187}
188
189#[derive(Debug, Clone, Serialize, Deserialize)]
198pub struct EventMetadata {
199 pub producer_id: Option<String>,
201 pub content_type: Option<String>,
203 pub event_type: Option<String>,
205 pub headers: std::collections::HashMap<String, String>,
207}
208
209impl Default for EventMetadata {
210 fn default() -> Self {
211 Self {
212 producer_id: None,
213 content_type: None,
214 event_type: None,
215 headers: std::collections::HashMap::new(),
216 }
217 }
218}
219
220#[derive(Debug, Clone, Serialize, Deserialize)]
246pub struct Event {
247 pub id: EventId,
249 pub topic: Topic,
251 pub partition: Partition,
253 pub offset: Option<Offset>,
255 pub timestamp: Timestamp,
257 pub data: EventData,
259 pub metadata: EventMetadata,
261}
262
263impl Event {
264 pub fn new(
275 id: EventId,
276 topic: Topic,
277 partition: Partition,
278 data: EventData,
279 ) -> Self {
280 Self {
281 id,
282 topic,
283 partition,
284 offset: None,
285 timestamp: Timestamp::now(),
286 data,
287 metadata: EventMetadata::default(),
288 }
289 }
290
291 pub fn with_metadata(
293 id: EventId,
294 topic: Topic,
295 partition: Partition,
296 data: EventData,
297 metadata: EventMetadata,
298 ) -> Self {
299 Self {
300 id,
301 topic,
302 partition,
303 offset: None,
304 timestamp: Timestamp::now(),
305 data,
306 metadata,
307 }
308 }
309
310 pub fn set_offset(&mut self, offset: Offset) {
312 self.offset = Some(offset);
313 }
314
315 pub fn estimated_size(&self) -> usize {
323 std::mem::size_of::<EventId>()
325 + self.topic.len()
326 + std::mem::size_of::<Partition>()
327 + std::mem::size_of::<Option<Offset>>()
328 + std::mem::size_of::<Timestamp>()
329 + self.data.len()
330 + self.metadata.headers.len() * 50 }
332
333 pub fn sort_key(&self) -> (Timestamp, EventId) {
335 (self.timestamp, self.id)
336 }
337}