use std::collections::HashMap;
use std::sync::Mutex;
use async_trait::async_trait;
use chrono::Utc;
use crate::error::Result;
use crate::event::{Event, EventRequest};
use crate::id::{EventId, SessionId};
#[async_trait]
pub trait EventLog: Send + Sync {
async fn append(&self, request: EventRequest) -> Result<Event>;
async fn read(&self, session_id: SessionId) -> Result<Vec<Event>>;
}
#[derive(Default)]
pub struct InMemoryEventLog {
sessions: Mutex<HashMap<SessionId, Vec<Event>>>,
}
impl InMemoryEventLog {
pub fn new() -> Self {
Self::default()
}
}
#[async_trait]
impl EventLog for InMemoryEventLog {
async fn append(&self, request: EventRequest) -> Result<Event> {
let mut sessions = self.sessions.lock().expect("event log poisoned");
let events = sessions.entry(request.session_id).or_default();
let sequence = events.len() as u64 + 1;
let event = request.into_event(EventId::new(), Utc::now(), sequence);
events.push(event.clone());
Ok(event)
}
async fn read(&self, session_id: SessionId) -> Result<Vec<Event>> {
let sessions = self.sessions.lock().expect("event log poisoned");
Ok(sessions.get(&session_id).cloned().unwrap_or_default())
}
}