use super::{event::EventLogReadMarker, Event, EventKind, EventLog, EventRecord, IntoEvent};
#[derive(Debug, thiserror::Error)]
pub enum EventRepoError {
#[error("failed to publish event")]
PublishFailed,
}
#[async_trait::async_trait]
pub trait EventRepo {
async fn entries_since_position(
&self,
stream_name: impl AsRef<str> + Send,
position: i64,
) -> Result<EventLog, EventRepoError>;
async fn publish<EventCandidate>(&self, event: EventCandidate) -> Result<(), EventRepoError>
where
EventCandidate: IntoEvent + Send;
async fn last(
&self,
stream_name: impl AsRef<str> + Send,
kind: EventKind,
) -> Option<EventRecord>;
async fn log_last_read(
&self,
stream_name: impl AsRef<str> + Send,
subscriber_name: impl AsRef<str> + Send,
position: i64,
) -> Result<(), EventRepoError> {
self.publish(Event::read_marker(stream_name, subscriber_name, position))
.await?;
Ok(())
}
async fn last_read_position(&self, stream_name: impl AsRef<str> + Send) -> i64 {
self.last(stream_name, EventKind::Marker)
.await
.and_then(|message| serde_json::from_slice::<EventLogReadMarker>(&message.data).ok())
.map(|marker| marker.position)
.unwrap_or(-1_i64)
}
async fn last_event_position(&self, stream_name: impl AsRef<str> + Send) -> i64 {
self.last(stream_name, EventKind::Entry)
.await
.map(|message| message.position)
.unwrap_or(-1_i64)
}
}