use std::collections::HashMap; use std::sync::Arc; use axum::async_trait; use churn_domain::{LogEvent, ServerEnrollReq}; use serde::{ser::SerializeStruct, Deserialize, Serialize}; use tokio::sync::{Mutex, RwLock}; use churn_capnp::CapnpPackExt; use crate::db::Db; #[derive(Clone)] pub struct EventService(Arc); impl EventService { pub fn new(db: Db) -> Self { Self(Arc::new(DefaultEventService::new(db))) } } impl std::ops::Deref for EventService { type Target = Arc; fn deref(&self) -> &Self::Target { &self.0 } } impl Default for EventService { fn default() -> Self { Self(Arc::new(DefaultEventService::default())) } } #[derive(Default)] struct DefaultEventService { db: Db, } impl DefaultEventService { pub fn new(db: Db) -> Self { Self { db } } } #[async_trait] pub trait EventServiceTrait { async fn append(&self, req: LogEvent) -> anyhow::Result<()>; async fn get_from_cursor(&self, cursor: uuid::Uuid) -> anyhow::Result>; async fn get_from_beginning(&self) -> anyhow::Result>; } #[async_trait] impl EventServiceTrait for DefaultEventService { async fn append(&self, req: LogEvent) -> anyhow::Result<()> { self.db .insert("events_log", &req.id.to_string(), &req.serialize_capnp()) .await; Ok(()) } async fn get_from_cursor(&self, cursor: uuid::Uuid) -> anyhow::Result> { let events = self.db.get_all("events_log").await?; let events = events .iter() .map(|e| LogEvent::deserialize_capnp(e)) .flatten() .skip_while(|item| item.id != cursor) .skip(1) .collect(); Ok(events) } async fn get_from_beginning(&self) -> anyhow::Result> { let events = self.db.get_all("events_log").await?; let events = events .iter() .map(|e| LogEvent::deserialize_capnp(e)) .flatten() .collect(); Ok(events) } }