pub trait CommandRepository<A: Aggregate>: Repository<A> {
// Provided method
fn execute<C, const N: usize>(
&self,
root: &mut AggregateRoot<A>,
command: C,
) -> impl Future<Output = Result<Execution<A, Self::Position, N>, ExecuteError<A::Error, Self::Error>>> + Send
where A: Handle<C, N>,
C: Send { ... }
}Expand description
The command-facing port: decide → save as one callable transaction.
Extends Repository<A> and inherits its load/save unchanged. The one
provided method rides on every repository via the blanket impl below — bare
EventStore and the
Snapshotting decorator alike.
Provided Methods§
Sourcefn execute<C, const N: usize>(
&self,
root: &mut AggregateRoot<A>,
command: C,
) -> impl Future<Output = Result<Execution<A, Self::Position, N>, ExecuteError<A::Error, Self::Error>>> + Send
fn execute<C, const N: usize>( &self, root: &mut AggregateRoot<A>, command: C, ) -> impl Future<Output = Result<Execution<A, Self::Position, N>, ExecuteError<A::Error, Self::Error>>> + Send
Decide command against root, persist the decided events atomically,
advance root, and return an Execution carrying the read-your-writes
position and the decided events.
Ok(Execution::Executed { position, events })— accepted and durable;positionis the$allposition the last event landed at (#330).Ok(Execution::Ignored)— the command was accepted and decided nothing (Handle::handlereturnedOk(None)); no append is issued, sorootkeeps its version, noGlobalSeqis burned, and a fresh aggregate stays streamless. Read the unchanged state offroot.Err(ExecuteError::Decide)— the aggregate rejected it; nothing persisted.Err(ExecuteError::Store)— the save failed (seeExecuteError::is_conflict).
Execution is a two-variant enum rather than Handle’s bare
Option (#330): once save returns a position, the accepted branch has
a second field to pair with the events — the exact symmetry with the
saga side’s Reaction. The no-op branch stays
positionless, since nothing was appended.
On a version conflict this returns Err(ExecuteError::Store(..)) with
is_conflict() == true and does not retry — retry is the runtime’s
job (CLAUDE.md rule 5), matching SagaRepository::react_and_save.
§Errors
See the variants above.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".