nitinol_protocol/io/
write.rs

1use std::fmt::Debug;
2use std::sync::Arc;
3use async_trait::async_trait;
4use time::OffsetDateTime;
5use nitinol_core::event::Event;
6use nitinol_core::identifier::{EntityId, ToEntityId};
7use crate::errors::ProtocolError;
8use crate::Payload;
9
10#[async_trait]
11pub trait Writer: 'static + Sync + Send {
12    async fn write(&self, aggregate_id: EntityId, payload: Payload) -> Result<(), ProtocolError>;
13}
14
15pub struct WriteProtocol {
16    writer: Arc<dyn Writer>
17}
18
19impl Debug for WriteProtocol {
20    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21        f.debug_struct("WriteProtocol").finish()
22    }
23}
24
25impl Clone for WriteProtocol {
26    fn clone(&self) -> Self {
27        Self { writer: Arc::clone(&self.writer) }
28    }
29}
30
31impl WriteProtocol {
32    pub fn new(provider: impl Writer) -> Self {
33        Self { writer: Arc::new(provider) }
34    }
35    
36    pub async fn write<E: Event>(&self, aggregate_id: impl ToEntityId, event: &E, seq: i64) -> Result<(), ProtocolError> {
37        let event = event.as_bytes().map_err(|e| ProtocolError::Write(Box::new(e)))?;
38        let aggregate_id = aggregate_id.to_entity_id();
39        self.writer
40            .write(aggregate_id.clone(), Payload {
41                id: aggregate_id.to_string(),
42                sequence_id: seq,
43                registry_key: E::EVENT_TYPE.to_string(),
44                bytes: event,
45                created_at: OffsetDateTime::now_utc()
46            })
47            .await
48    }
49}