use crate::{
aggregate::{Aggregate, AggregateEvent, AggregateId},
types::{
CqrsError, EventNumber, Precondition, Since, SnapshotRecommendation, Version,
VersionedAggregate, VersionedEvent,
},
};
pub trait EventSource<A, E>
where
A: Aggregate,
E: AggregateEvent<A>,
{
type Events: IntoIterator<Item = VersionedEvent<E>>;
type Error: CqrsError;
fn read_events<I>(
&self,
id: &I,
since: Since,
max_count: Option<u64>,
) -> Result<Option<Self::Events>, Self::Error>
where
I: AggregateId<A>;
}
pub trait EventSink<A, E, M>
where
A: Aggregate,
E: AggregateEvent<A>,
{
type Error: CqrsError;
fn append_events<I>(
&self,
id: &I,
events: &[E],
precondition: Option<Precondition>,
metadata: M,
) -> Result<EventNumber, Self::Error>
where
I: AggregateId<A>;
}
pub trait SnapshotSource<A>
where
A: Aggregate,
{
type Error: CqrsError;
fn get_snapshot<I>(&self, id: &I) -> Result<Option<VersionedAggregate<A>>, Self::Error>
where
I: AggregateId<A>;
}
pub trait SnapshotSink<A>
where
A: Aggregate,
{
type Error: CqrsError;
fn persist_snapshot<I>(
&self,
id: &I,
aggregate: &A,
version: Version,
last_snapshot_version: Option<Version>,
) -> Result<Version, Self::Error>
where
I: AggregateId<A>;
}
pub trait SnapshotStrategy {
fn snapshot_recommendation(
&self,
version: Version,
last_snapshot_version: Option<Version>,
) -> SnapshotRecommendation;
}
#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq)]
pub struct NeverSnapshot;
impl SnapshotStrategy for NeverSnapshot {
fn snapshot_recommendation(&self, _: Version, _: Option<Version>) -> SnapshotRecommendation {
SnapshotRecommendation::DoNotSnapshot
}
}
#[derive(Clone, Copy, Debug, Default, Hash, PartialEq, Eq)]
pub struct AlwaysSnapshot;
impl SnapshotStrategy for AlwaysSnapshot {
fn snapshot_recommendation(&self, _: Version, _: Option<Version>) -> SnapshotRecommendation {
SnapshotRecommendation::ShouldSnapshot
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{AggregateCommand, AggregateEvent, Event};
use void::Void;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct TestAggregate;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct TestEvent;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct TestCommand;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct TestMetadata;
impl Aggregate for TestAggregate {
fn aggregate_type() -> &'static str {
"test"
}
}
impl AggregateEvent<TestAggregate> for TestEvent {
fn apply_to(self, _aggregate: &mut TestAggregate) {}
}
impl AggregateCommand<TestAggregate> for TestCommand {
type Error = Void;
type Event = TestEvent;
type Events = Vec<TestEvent>;
fn execute_on(self, _aggregate: &TestAggregate) -> Result<Self::Events, Self::Error> {
Ok(Vec::default())
}
}
impl Event for TestEvent {
fn event_type(&self) -> &'static str {
"test"
}
}
}