1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//! Write-path metadata production for the typed facade (#344).
//!
//! Metadata is attached to events as they are persisted through
//! [`Repository::save`](crate::Repository::save), [`EventStore::save_with`](crate::EventStore::save_with),
//! and all higher-level callers built on top of the facade (saga reactions,
//! command execution, snapshot decorator saves). The read side already exposes
//! `Option<bytes::Bytes>` on every envelope; the provider closes the write-side
//! gap without forcing callers to drop to [`RawEventStore`](crate::store::RawEventStore).
use crate;
use Version;
/// Write-path metadata producer for events of type `E`.
///
/// A provider is called once per event, post-encode, with the version the event
/// will be assigned, a reference to the event, and the validated payload bytes
/// that will be persisted. It returns `Some(Metadata)` to attach metadata to the
/// envelope, or `None` to leave metadata absent.
///
/// The provider is infallible by design. Cap errors (e.g. `ValueError::MetadataTooLong`)
/// are the provider author's concern at `Metadata` construction; the facade
/// never re-validates an already-validated [`Metadata`] value.
///
/// # No-op default
///
/// The `()` impl always returns `None`. It is the inert default slot for the
/// `M = ()` type parameter on [`EventStore`](crate::EventStore) and
/// [`RepositoryBuilder`](crate::RepositoryBuilder), mirroring the role
/// [`NoSnapshot`](crate::NoSnapshot) plays on the snapshot axis.
///
/// # Closure blanket impl
///
/// A plain `Fn(Version, &E, &Payload) -> Option<Metadata>` closure implements
/// the trait, so callers can write `.metadata(|v, e, p| ...)` without naming
/// the trait explicitly.
///
/// # Stateful providers
///
/// The provider is called through `&self`; statefulness (for example an HLC
/// clock or a monotonic counter) uses interior mutability. This is the same
/// contract [`WakeSource`](crate::wake::WakeSource) carries: shared behind an
/// `Arc`, mutated via atomics or a mutex if needed.
///
/// # Documented tension: upcasting vs. byte-level signatures
///
/// Metadata is never upcasted. A signature over payload bytes couples signature
/// validity to the frozen payload encoding: if an upcaster rewrites the payload
/// on the read path, the signature stops verifying. Raw subscription paths see
/// pre-upcast bytes (verification works); the typed facade `load` path replays
/// typed events and the consumer never sees bytes. KERI-style bridges handle
/// schema evolution via digest chains, not byte stability.
/// Inert metadata provider — always returns `None`.
///
/// This is the default `M = ()` slot on [`EventStore`](crate::EventStore) and
/// [`RepositoryBuilder`](crate::RepositoryBuilder), so existing callers that do
/// not call [`.metadata()`](RepositoryBuilder::metadata) behave exactly as
/// before: every event is persisted with metadata absent.
/// Closure blanket impl for `MetadataProvider`.
///
/// Lets callers pass a plain closure to `.metadata(|version, event, payload| ...)`
/// without naming the trait. The `Send + Sync + 'static` bounds are required so
/// the closure can be held by the facade alongside the codec.