#[non_exhaustive]pub enum Expected {
Unwritten,
Seq(u64),
}Expand description
What a caller believes a stream’s head to be, as of when it last looked.
A named type rather than an Option<u64> or a zero sentinel. The two cases
are not “some head” and “no head” — they are two different claims, and the
empty one is the one everybody gets wrong. Rails Event Store spells it
-1, others spell it 0, and both produce off-by-one bug reports;
Equinox hides the number entirely rather than let it into domain code.
Naming the empty case is the mitigation available to a store that has to
expose it at all.
§Two variants are the surface
Stores that run as a service tend to offer four: these two, an Any that
checks nothing, and a StreamExists that checks only that the stream was
written to. Any is spelled here by not calling
EventStore::append_expecting. StreamExists is absent on purpose.
KurrentDB added it so an append could refuse a soft-deleted stream — a
stream that was written, then marked gone. That third state has nothing to
stand on here: the trait has no delete, retention leaves the counter
alone, and a stream has either been written or it has not. Past the
existence check StreamExists is Any, so it also adds nothing to
concurrency that Expected::Seq does not already give.
The question it is usually reached for — “did the command that creates
this stream run?” — is a fact about the domain, and it goes where domain
facts go: a key under meta on the creating event, read through
crate::log::Filter. See crate::event on why lifecycle lives there.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
Unwritten
Nothing has ever been appended to this stream.
Not the same as “the stream reads empty”. Retention can empty a stream whose counter stands at 50, and a caller that meant “this is a new order” must not be told yes about an order that was archived. The check is against what the stream’s counter records, not against the rows that survive.
Seq(u64)
The last event appended to this stream has this seq.
A seq, not a crate::position::Position: the claim is about one
stream, and the two coordinates have different scopes.