ddd_toolkit_core/event_versioning.rs
1use std::marker::PhantomData;
2
3/// **English:**<br>
4/// Event name and schema version supplied by the application.
5/// Fields are public and unvalidated: an empty name or version zero is accepted. Equality compares
6/// both fields. This value supplies no registry, serialization format, or migration dispatch.
7///
8/// **日本語:**<br>
9/// アプリケーションが指定するイベント名とスキーマバージョンです。
10/// フィールドは公開され検証されません。空の名前やバージョンゼロも許容します。等値比較は
11/// 両フィールドを比較します。レジストリー、直列化形式、移行の振り分けは提供しません。
12#[derive(Clone, Copy, Debug, Eq, PartialEq)]
13pub struct EventIdentity {
14 /// **English:**<br>
15 /// Static event name; uniqueness and naming conventions are application-defined.
16 ///
17 /// **日本語:**<br>
18 /// 静的なイベント名です。一意性と命名規則はアプリケーションが定めます。
19 pub name: &'static str,
20
21 /// **English:**<br>
22 /// Numeric schema version, with no enforced starting value or ordering policy.
23 ///
24 /// **日本語:**<br>
25 /// 数値のスキーマバージョンです。開始値や順序の方針は強制しません。
26 pub version: u32,
27}
28
29/// **English:**<br>
30/// Type-level event identity independent of any particular event instance.
31/// No [`crate::DomainEvent`] bound is required, and the trait does not validate the returned identity.
32///
33/// **日本語:**<br>
34/// 個々のイベントインスタンスとは独立した、型単位のイベント識別情報です。
35/// [`crate::DomainEvent`] の境界は要求せず、返された識別情報も検証しません。
36pub trait VersionedEvent {
37 /// **English:**<br>
38 /// Returns the name and schema version chosen for this event type.
39 /// Implementations define the mapping; no instance data is passed to this function.
40 ///
41 /// **日本語:**<br>
42 /// このイベント型に選んだ名前とスキーマバージョンを返します。
43 /// 対応付けは実装が定め、この関数にはインスタンスのデータを渡しません。
44 fn identity() -> EventIdentity;
45}
46
47/// **English:**<br>
48/// Fallible owned transformation from an event representation back to the same Rust type.
49/// Versions can be represented inside that type, but checking or advancing them is the
50/// implementation's responsibility. No [`VersionedEvent`] bound or automatic version selection is used.
51///
52/// **日本語:**<br>
53/// イベント表現を所有して受け取り、同じ Rust 型へ変換する、失敗し得る操作です。
54/// 型の内部にバージョンを表現できますが、その検査や更新は実装が担います。
55/// [`VersionedEvent`] の境界や自動的なバージョン選択は用いません。
56pub trait EventUpcaster<Event> {
57 /// **English:**<br>
58 /// Transformation failure forwarded unchanged by [`UpcasterChain::apply`].
59 ///
60 /// **日本語:**<br>
61 /// [`UpcasterChain::apply`] が変更せず伝播する変換の失敗です。
62 type Error;
63
64 /// **English:**<br>
65 /// Consumes `event`, returning its transformed representation or an error.
66 /// The input is not returned on error; side effects and panic conditions depend on the upcaster.
67 ///
68 /// **日本語:**<br>
69 /// `event` を消費し、変換後の表現またはエラーを返します。
70 /// エラー時に入力は返しません。副作用とパニックの条件は変換器に依存します。
71 fn upcast(&self, event: Event) -> Result<Event, Self::Error>;
72}
73
74/// **English:**<br>
75/// Insertion-ordered sequence of upcasters of a single concrete type.
76/// Each stage consumes the preceding output. The chain does not select stages by event identity,
77/// sort versions, or restore an event after failure. Use an enum or another common upcaster type
78/// when stages need different behaviors. It stores no event value and adds no locking.
79///
80/// Add stages explicitly; each successful result becomes the next input.
81///
82/// **日本語:**<br>
83/// 同じ具体型の変換器を追加順に保持する列です。
84/// 各段階は直前の出力を消費します。イベント識別情報による段階の選択、バージョンの並べ替え、
85/// 失敗後のイベント復元はしません。異なる動作の段階には列挙型などの共通の変換器型を用います。
86/// イベント値は保持せず、ロックも追加しません。
87///
88/// 段階を明示的に追加すると、各段階の成功結果が次の入力になります。
89///
90/// # Example / 使用例
91///
92/// ```rust
93/// use ddd_toolkit_core::{EventUpcaster, UpcasterChain};
94///
95/// struct Append(&'static str);
96/// impl EventUpcaster<String> for Append {
97/// type Error = std::convert::Infallible;
98/// fn upcast(&self, mut event: String) -> Result<String, Self::Error> {
99/// event.push_str(self.0);
100/// Ok(event)
101/// }
102/// }
103/// let mut chain = UpcasterChain::new();
104/// chain.push(Append("-v2"));
105/// chain.push(Append("-v3"));
106/// assert_eq!(chain.apply(String::from("v1")).unwrap(), "v1-v2-v3");
107/// assert_eq!(chain.len(), 2);
108/// ```
109pub struct UpcasterChain<Event, Upcaster> {
110 upcasters: Vec<Upcaster>,
111 marker: PhantomData<fn() -> Event>,
112}
113
114impl<Event, Upcaster> Default for UpcasterChain<Event, Upcaster> {
115 fn default() -> Self {
116 Self::new()
117 }
118}
119
120impl<Event, Upcaster> UpcasterChain<Event, Upcaster> {
121 /// **English:**<br>
122 /// Creates an empty chain, also used by [`Default::default`].
123 /// Applying an empty chain returns the input unchanged.
124 ///
125 /// **日本語:**<br>
126 /// [`Default::default`] でも使う空の列を作ります。
127 /// 空の列を適用すると、入力を変更せず返します。
128 pub fn new() -> Self {
129 Self {
130 upcasters: Vec::new(),
131 marker: PhantomData,
132 }
133 }
134
135 /// **English:**<br>
136 /// Appends `upcaster` as the last stage without inspecting its version or running it.
137 ///
138 /// **日本語:**<br>
139 /// バージョンを調べたり実行したりせず、`upcaster` を最後の段階に追加します。
140 pub fn push(&mut self, upcaster: Upcaster) {
141 self.upcasters.push(upcaster);
142 }
143
144 /// **English:**<br>
145 /// Returns the number of stored stages, not the number of supported event versions.
146 ///
147 /// **日本語:**<br>
148 /// 対応するイベントバージョン数ではなく、保持する段階数を返します。
149 pub fn len(&self) -> usize {
150 self.upcasters.len()
151 }
152
153 /// **English:**<br>
154 /// Returns `true` when no upcasters have been added.
155 ///
156 /// **日本語:**<br>
157 /// 変換器を一つも追加していない場合に `true` を返します。
158 pub fn is_empty(&self) -> bool {
159 self.upcasters.is_empty()
160 }
161
162 /// **English:**<br>
163 /// Runs all stages in insertion order and returns the final owned event.
164 /// The first error stops evaluation and is returned unchanged; later stages are not called.
165 /// Earlier side effects are not rolled back. An empty chain returns `Ok(event)`.
166 /// Panics from a stage propagate, and the chain itself remains stored for future calls.
167 ///
168 /// **日本語:**<br>
169 /// 全段階を追加順に実行し、最後の所有されたイベントを返します。
170 /// 最初のエラーで評価を止め、変更せず返します。後続の段階は呼び出しません。
171 /// 先行する副作用は取り消しません。空の列は `Ok(event)` を返します。
172 /// 段階のパニックは伝播し、列自体は後続の呼び出しにも使えるよう保持されます。
173 pub fn apply(&self, mut event: Event) -> Result<Event, Upcaster::Error>
174 where
175 Upcaster: EventUpcaster<Event>,
176 {
177 for upcaster in &self.upcasters {
178 event = upcaster.upcast(event)?;
179 }
180 Ok(event)
181 }
182}