Skip to main content

CommandRepository

Trait CommandRepository 

Source
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§

Source

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,

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; position is the $all position the last event landed at (#330).
  • Ok(Execution::Ignored) — the command was accepted and decided nothing (Handle::handle returned Ok(None)); no append is issued, so root keeps its version, no GlobalSeq is burned, and a fresh aggregate stays streamless. Read the unchanged state off root.
  • Err(ExecuteError::Decide) — the aggregate rejected it; nothing persisted.
  • Err(ExecuteError::Store) — the save failed (see ExecuteError::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".

Implementors§