Skip to main content

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}