pub trait EventStore: Send + Sync {
type Id: Clone + Send + Sync + 'static;
type Position: Clone + PartialEq + Debug + Send + Sync + 'static;
type Error: Error + Send + Sync + 'static;
type Metadata: Send + Sync + 'static;
type Data: Clone + Send + Sync + 'static;
// Required methods
fn decode_event<E>(
&self,
stored: &StoredEvent<Self::Id, Self::Position, Self::Data, Self::Metadata>,
) -> Result<E, Self::Error>
where E: DomainEvent + DeserializeOwned;
fn stream_version<'a>(
&'a self,
aggregate_kind: &'a str,
aggregate_id: &'a Self::Id,
) -> impl Future<Output = Result<Option<Self::Position>, Self::Error>> + Send + 'a;
fn commit_events<'a, E>(
&'a self,
aggregate_kind: &'a str,
aggregate_id: &'a Self::Id,
events: NonEmpty<E>,
metadata: &'a Self::Metadata,
) -> impl Future<Output = Result<Committed<Self::Position>, CommitError<Self::Error>>> + Send + 'a
where E: EventKind + Serialize + Send + Sync + 'a,
Self::Metadata: Clone;
fn commit_events_optimistic<'a, E>(
&'a self,
aggregate_kind: &'a str,
aggregate_id: &'a Self::Id,
expected_version: Option<Self::Position>,
events: NonEmpty<E>,
metadata: &'a Self::Metadata,
) -> impl Future<Output = Result<Committed<Self::Position>, OptimisticCommitError<Self::Position, Self::Error>>> + Send + 'a
where E: EventKind + Serialize + Send + Sync + 'a,
Self::Metadata: Clone;
fn load_events<'a>(
&'a self,
filters: &'a [EventFilter<Self::Id, Self::Position>],
) -> impl Future<Output = LoadEventsResult<Self::Id, Self::Position, Self::Data, Self::Metadata, Self::Error>> + Send + 'a;
}Expand description
Abstraction over the persistence layer for event streams.
This trait supports both stream-based and type-partitioned storage implementations. Stores own event serialisation/deserialisation.
Associated types allow stores to customise their behaviour:
Id: Aggregate identifier typePosition: Ordering strategy (()for stream-based,u64for global ordering)Metadata: Infrastructure metadata type (timestamps, causation tracking, etc.)Data: Serialised event payload type (e.g.,serde_json::Valuefor JSON)
Required Associated Types§
Sourcetype Id: Clone + Send + Sync + 'static
type Id: Clone + Send + Sync + 'static
Aggregate identifier type.
This type must be clonable so repositories can reuse IDs across calls.
Common choices: String, Uuid, or custom ID types.
Required Methods§
Sourcefn decode_event<E>(
&self,
stored: &StoredEvent<Self::Id, Self::Position, Self::Data, Self::Metadata>,
) -> Result<E, Self::Error>where
E: DomainEvent + DeserializeOwned,
fn decode_event<E>(
&self,
stored: &StoredEvent<Self::Id, Self::Position, Self::Data, Self::Metadata>,
) -> Result<E, Self::Error>where
E: DomainEvent + DeserializeOwned,
Decode a stored event into a concrete event type.
Deserialises the data field of a StoredEvent back into a domain
event.
§Errors
Returns an error if deserialisation fails.
Sourcefn stream_version<'a>(
&'a self,
aggregate_kind: &'a str,
aggregate_id: &'a Self::Id,
) -> impl Future<Output = Result<Option<Self::Position>, Self::Error>> + Send + 'a
fn stream_version<'a>( &'a self, aggregate_kind: &'a str, aggregate_id: &'a Self::Id, ) -> impl Future<Output = Result<Option<Self::Position>, Self::Error>> + Send + 'a
Get the current version (latest position) for an aggregate stream.
Returns None for streams with no events.
§Errors
Returns a store-specific error when the operation fails.
Sourcefn commit_events<'a, E>(
&'a self,
aggregate_kind: &'a str,
aggregate_id: &'a Self::Id,
events: NonEmpty<E>,
metadata: &'a Self::Metadata,
) -> impl Future<Output = Result<Committed<Self::Position>, CommitError<Self::Error>>> + Send + 'a
fn commit_events<'a, E>( &'a self, aggregate_kind: &'a str, aggregate_id: &'a Self::Id, events: NonEmpty<E>, metadata: &'a Self::Metadata, ) -> impl Future<Output = Result<Committed<Self::Position>, CommitError<Self::Error>>> + Send + 'a
Commit events to an aggregate stream without version checking.
Events are serialised and persisted atomically. No conflict detection is performed (last-writer-wins).
§Errors
Returns CommitError::Serialization if an event fails to serialise,
or CommitError::Store if persistence fails.
Sourcefn commit_events_optimistic<'a, E>(
&'a self,
aggregate_kind: &'a str,
aggregate_id: &'a Self::Id,
expected_version: Option<Self::Position>,
events: NonEmpty<E>,
metadata: &'a Self::Metadata,
) -> impl Future<Output = Result<Committed<Self::Position>, OptimisticCommitError<Self::Position, Self::Error>>> + Send + 'a
fn commit_events_optimistic<'a, E>( &'a self, aggregate_kind: &'a str, aggregate_id: &'a Self::Id, expected_version: Option<Self::Position>, events: NonEmpty<E>, metadata: &'a Self::Metadata, ) -> impl Future<Output = Result<Committed<Self::Position>, OptimisticCommitError<Self::Position, Self::Error>>> + Send + 'a
Commit events to an aggregate stream with optimistic concurrency control.
Events are serialised and persisted atomically. The commit fails if:
expected_versionisSome(v)and the current version differs fromvexpected_versionisNoneand the stream already has events (new aggregate expected)
§Errors
Returns OptimisticCommitError::Serialization if an event fails to
serialise, OptimisticCommitError::Conflict if the version check
fails, or OptimisticCommitError::Store if persistence fails.
Sourcefn load_events<'a>(
&'a self,
filters: &'a [EventFilter<Self::Id, Self::Position>],
) -> impl Future<Output = LoadEventsResult<Self::Id, Self::Position, Self::Data, Self::Metadata, Self::Error>> + Send + 'a
fn load_events<'a>( &'a self, filters: &'a [EventFilter<Self::Id, Self::Position>], ) -> impl Future<Output = LoadEventsResult<Self::Id, Self::Position, Self::Data, Self::Metadata, Self::Error>> + Send + 'a
Load events matching the specified filters.
Each filter describes an event kind and optional aggregate identity:
EventFilter::for_eventloads every event of the given kindEventFilter::for_aggregatenarrows to a single aggregate instance
The store optimises based on its storage model and returns events merged by position (if positions are available).
§Errors
Returns a store-specific error when loading fails.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.