ddd_toolkit_core/snapshot.rs
1use crate::event_store::StreamRevision;
2use crate::{AggregateRoot, Entity};
3
4/// **English:**<br>
5/// Owned aggregate state paired with the last event revision it represents.
6/// No identifier or schema version is added; include validation metadata in `S` when needed.
7///
8/// **日本語:**<br>
9/// 集約状態と、その状態が反映する最後のイベントのリビジョンを所有します。
10/// 識別子やスキーマバージョンは追加しません。検証用メタデータは必要に応じて `S` に含めます。
11///
12/// # Example / 使用例
13///
14/// ```rust
15/// use ddd_toolkit_core::{AggregateSnapshot, StreamRevision};
16/// let snapshot = AggregateSnapshot::new(42_u64, StreamRevision::new(3));
17/// assert_eq!(*snapshot.state(), 42);
18/// assert_eq!(snapshot.into_parts(), (42, StreamRevision::new(3)));
19/// ```
20#[derive(Debug, Eq, PartialEq)]
21pub struct AggregateSnapshot<S> {
22 state: S,
23 revision: StreamRevision,
24}
25
26impl<S> AggregateSnapshot<S> {
27 /// **English:**<br>
28 /// Pairs `state` with `revision` without checking consistency or compatibility.
29 ///
30 /// **日本語:**<br>
31 /// 整合性や互換性を検証せず、`state` と `revision` を組み合わせます。
32 pub fn new(state: S, revision: StreamRevision) -> Self {
33 Self { state, revision }
34 }
35
36 /// **English:**<br>
37 /// Borrows the stored aggregate state.
38 ///
39 /// **日本語:**<br>
40 /// 保存された集約状態を借用します。
41 pub fn state(&self) -> &S {
42 &self.state
43 }
44
45 /// **English:**<br>
46 /// Returns the last event revision represented by the state.
47 ///
48 /// **日本語:**<br>
49 /// 状態が反映する最後のイベントのリビジョンを返します。
50 pub fn revision(&self) -> StreamRevision {
51 self.revision
52 }
53
54 /// **English:**<br>
55 /// Consumes the snapshot, returning state and revision without cloning.
56 ///
57 /// **日本語:**<br>
58 /// スナップショットを消費し、複製せずに状態とリビジョンを返します。
59 pub fn into_parts(self) -> (S, StreamRevision) {
60 (self.state, self.revision)
61 }
62}
63
64/// **English:**<br>
65/// Aggregate-defined snapshot classification used by [`crate::replay_with_optional_snapshot`].
66/// Both `Stale` and `Inapplicable` trigger full replay; an older but usable snapshot may be `Applicable`.
67///
68/// **日本語:**<br>
69/// [`crate::replay_with_optional_snapshot`] で使う集約定義のスナップショット分類です。
70/// `Stale` と `Inapplicable` は全件再生を選択します。古くても利用可能なら `Applicable` にできます。
71#[derive(Clone, Copy, Debug, Eq, PartialEq)]
72pub enum SnapshotUse {
73 /// **English:**<br>
74 /// Restore this snapshot and replay only later events.
75 ///
76 /// **日本語:**<br>
77 /// このスナップショットを復元し、後続イベントのみ再生します。
78 Applicable,
79 /// **English:**<br>
80 /// Reject this snapshot as stale and replay the complete history.
81 ///
82 /// **日本語:**<br>
83 /// 古いスナップショットとして採用せず、完全な履歴を再生します。
84 Stale,
85 /// **English:**<br>
86 /// Reject this snapshot as incompatible and replay the complete history.
87 ///
88 /// **日本語:**<br>
89 /// 互換性のないスナップショットとして採用せず、完全な履歴を再生します。
90 Inapplicable,
91}
92
93/// **English:**<br>
94/// Snapshot lookup failure, distinct from a missing snapshot.
95///
96/// **日本語:**<br>
97/// スナップショットの検索失敗です。スナップショットの不在とは区別されます。
98#[derive(Debug, Eq, PartialEq)]
99pub enum SnapshotLoadError<E> {
100 /// **English:**<br>
101 /// Error reported by the storage adapter.
102 ///
103 /// **日本語:**<br>
104 /// ストレージアダプターが報告したエラーです。
105 Adapter(E),
106}
107
108/// **English:**<br>
109/// Failure to persist a snapshot.
110///
111/// **日本語:**<br>
112/// スナップショットの永続化失敗です。
113#[derive(Debug, Eq, PartialEq)]
114pub enum SnapshotSaveError<E> {
115 /// **English:**<br>
116 /// Storage adapter error during saving.
117 ///
118 /// **日本語:**<br>
119 /// 保存時のストレージアダプターエラーです。
120 Adapter(E),
121}
122
123/// **English:**<br>
124/// Synchronous storage boundary for snapshots indexed by aggregate identifier.
125/// Implementations define replacement policy, durability, synchronization, and panic conditions.
126/// Saving a snapshot does not itself append events or validate the snapshot against an event stream.
127///
128/// **日本語:**<br>
129/// 集約識別子をキーとするスナップショットの同期ストレージ境界です。
130/// 置換方針、永続性、同期、パニック条件は実装が定めます。
131/// 保存自体はイベント追加やイベントストリームに対するスナップショットの検証を行いません。
132pub trait SnapshotStore {
133 /// **English:**<br>
134 /// Aggregate defining the snapshot lookup identifier.
135 ///
136 /// **日本語:**<br>
137 /// スナップショット検索の識別子を定める集約です。
138 type Aggregate: AggregateRoot;
139 /// **English:**<br>
140 /// State representation stored in each snapshot.
141 ///
142 /// **日本語:**<br>
143 /// 各スナップショットに保存する状態の表現です。
144 type State;
145 /// **English:**<br>
146 /// Adapter-specific persistence error.
147 ///
148 /// **日本語:**<br>
149 /// アダプター固有の永続化エラーです。
150 type Error;
151
152 /// **English:**<br>
153 /// Loads a snapshot for `id`; `Ok(None)` means none is available.
154 /// Storage failures use [`SnapshotLoadError::Adapter`] rather than the absence result.
155 ///
156 /// **日本語:**<br>
157 /// `id` のスナップショットを読み込みます。`Ok(None)` は不在を表します。
158 /// ストレージ障害は不在ではなく [`SnapshotLoadError::Adapter`] で返します。
159 fn load(
160 &self,
161 id: &<Self::Aggregate as Entity>::Id,
162 ) -> Result<Option<AggregateSnapshot<Self::State>>, SnapshotLoadError<Self::Error>>;
163
164 /// **English:**<br>
165 /// Consumes and saves `snapshot` for `id`, returning an adapter error on failure.
166 /// The snapshot is not returned on error; replacement and retry behavior depend on the adapter.
167 ///
168 /// **日本語:**<br>
169 /// `id` に対して `snapshot` を消費して保存し、失敗時はアダプターエラーを返します。
170 /// エラー時にスナップショットは返されません。置換や再試行の挙動はアダプターに依存します。
171 fn save(
172 &mut self,
173 id: &<Self::Aggregate as Entity>::Id,
174 snapshot: AggregateSnapshot<Self::State>,
175 ) -> Result<(), SnapshotSaveError<Self::Error>>;
176}