use crate::DbError;
use crate::pickle::Pickle;
use eventastic::aggregate::Aggregate;
use eventastic::event::{DomainEvent, EventStoreEvent};
use eventastic::repository::Snapshot;
use sqlx::types::Uuid;
type EventResult<T, E> = Result<
EventStoreEvent<<T as Aggregate>::DomainEvent>,
DbError<
E,
<<T as Aggregate>::DomainEvent as Pickle>::Error,
<T as Pickle>::Error,
<<T as Aggregate>::SideEffect as Pickle>::Error,
>,
>;
type SnapshotResult<T, E> = Result<
Snapshot<T>,
DbError<
E,
<<T as Aggregate>::DomainEvent as Pickle>::Error,
<T as Pickle>::Error,
<<T as Aggregate>::SideEffect as Pickle>::Error,
>,
>;
#[derive(Debug, sqlx::FromRow)]
pub(crate) struct PartialEventRow {
pub event_id: Uuid,
pub version: i64,
pub event: Vec<u8>,
}
impl PartialEventRow {
pub fn to_event<T, E>(row: PartialEventRow) -> EventResult<T, E>
where
T: Aggregate + Pickle,
T::DomainEvent: DomainEvent<EventId = Uuid> + Pickle,
T::SideEffect: Pickle,
{
let row_version = u64::try_from(row.version).map_err(|_| DbError::InvalidVersionNumber)?;
T::DomainEvent::unpickle(&row.event)
.map(|e| EventStoreEvent {
id: row.event_id,
event: e,
version: row_version,
})
.map_err(DbError::EventPicklingError)
}
}
#[derive(sqlx::FromRow)]
pub(crate) struct PartialSnapshotRow {
pub aggregate: Vec<u8>,
pub snapshot_version: i64,
pub version: i64,
}
impl PartialSnapshotRow {
pub fn to_snapshot<T, E>(row: PartialSnapshotRow) -> SnapshotResult<T, E>
where
T: Aggregate + Pickle,
T::DomainEvent: DomainEvent<EventId = Uuid> + Pickle,
T::SideEffect: Pickle,
{
let version = u64::try_from(row.version).map_err(|_| DbError::InvalidVersionNumber)?;
let snapshot_version =
u64::try_from(row.snapshot_version).map_err(|_| DbError::InvalidSnapshotVersion)?;
let aggregate: T = T::unpickle(&row.aggregate).map_err(DbError::SnapshotPicklingError)?;
Ok(Snapshot {
aggregate,
version,
snapshot_version,
})
}
}
pub(crate) mod utils {
use crate::DbError;
pub fn version_to_i64<EP, E, S, SE>(version: u64) -> Result<i64, DbError<EP, E, S, SE>> {
i64::try_from(version).map_err(|_| DbError::InvalidVersionNumber)
}
pub fn snapshot_version_to_i64<EP, E, S, SE>(
version: u64,
) -> Result<i64, DbError<EP, E, S, SE>> {
i64::try_from(version).map_err(|_| DbError::InvalidSnapshotVersion)
}
}