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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
//! **English:**<br>
//! Derive value objects, identity-based entities, domain-event markers,
//! and aggregate event queues for `ddd-toolkit-core`.
//!
//! Add both `ddd-toolkit-macro` and `ddd-toolkit-core` to your dependencies.
//! Expansion resolves the core package by name, including renamed dependencies;
//! a facade dependency alone is not resolved. These macros generate implementations
//! at compile time, not runtime synchronization or persistence.
//!
//! Use [`ValueObject`] for field-based equality, [`Entity`] for identity-based
//! equality, [`DomainEvent`] for event types, and [`AggregateRoot`] for a draining
//! event queue. Do not separately derive traits that a macro already implements.
//!
//! **日本語:**<br>
//! `ddd-toolkit-core` 向けに、値オブジェクト、識別子で比較する
//! エンティティ、ドメインイベントのマーカー、集約のイベントキューを導出します。
//!
//! 依存関係には `ddd-toolkit-macro` と `ddd-toolkit-core` の両方が必要です。
//! コアのパッケージ名から参照先を解決するため依存の別名に対応しますが、
//! ファサードだけの依存は解決しません。実装をコンパイル時に生成するもので、
//! 実行時の同期や永続化は行いません。
//!
//! フィールドの値で比較する型には [`ValueObject`]、識別子で比較する型には
//! [`Entity`]、イベント型には [`DomainEvent`]、イベントを取り出して空にする
//! キューには [`AggregateRoot`] を使います。生成済みのトレイトを重複して導出しないでください。
//!
//! # Example / 使用例
//!
//! ```rust
//! use ddd_toolkit_macro::ValueObject;
//!
//! #[derive(ValueObject)]
//! struct Quantity(u32);
//!
//! let quantity = Quantity::new(3);
//! assert_eq!(quantity.as_inner(), &3);
//! assert_eq!(quantity.into_inner(), 3);
//! ```
use TokenStream;
use parse_macro_input;
/// **English:**<br>
/// Implements `ddd_toolkit_core::ValueObject` and value-based
/// `Debug`, `Clone`, `PartialEq`, `Eq`, and `Hash`, with corresponding field bounds.
///
/// Accepts nonempty named or tuple structs and nonempty enums, not unions or unit
/// structs. A single-field struct exposes that field as `Inner`, `as_inner`, and
/// `into_inner`; multi-field structs and enums use `Self` instead. Structs get
/// `new` with fields in declaration order. Multi-field structs also get borrowed
/// accessors named after fields, or `field_0`, `field_1`, etc. for tuple fields.
/// Enums get `new_<variant>`, `is_<variant>`, and `as_<variant>`, using the fully
/// lowercased variant name (not snake case). Variant accessors return `None` for
/// another variant, `Some(())` for unit variants, or a tuple of field references.
/// Lowercased variant names must be distinct; generated names must not collide
/// with other methods or field accessors.
///
/// `#[value_object(validate = path, error = ErrorType)]` replaces `new` with
/// `try_new` (or `try_new_<variant>`). Both options are required together. The
/// validator receives `&Inner` for a single-field struct and `&Self` otherwise,
/// returns `Result<(), ErrorType>`, and runs before the constructor returns the
/// value. Its error is propagated; its panics are not caught. Validated struct
/// fields cannot be unrestricted `pub`. Restricted visibility, direct construction
/// inside the defining module, and enum variants can still bypass validation.
///
/// `#[value_object(serde)]` additionally generates serialization through the core
/// crate's serde re-export; enable the core crate's `serde` feature. Single-field
/// structs serialize as their inner value, named structs as structs, tuple structs
/// as tuples, and enums as externally tagged variants. Single-field tuple variants
/// use Serde's newtype format; other tuple variants use tuple format.
/// Deserialization runs validation when configured,
/// mapping its errors to `value object validation failed`. Serialization generation
/// is selected by this attribute, not by a feature on the macro crate.
/// Invalid shapes, duplicate or unknown options, and missing core dependencies
/// produce compile errors; field types must satisfy the generated trait bounds.
///
/// **日本語:**<br>
/// `ddd_toolkit_core::ValueObject` と値に基づく `Debug`、`Clone`、
/// `PartialEq`、`Eq`、`Hash` を、各フィールドに必要な境界付きで実装します。
///
/// 空でない名前付き・タプル構造体と列挙型に対応し、共用体やユニット構造体は拒否します。
/// 単一フィールド構造体の `Inner`、`as_inner`、`into_inner` はそのフィールドを扱い、
/// 複数フィールド構造体と列挙型では `Self` を扱います。構造体には宣言順の引数を取る
/// `new` を生成します。複数フィールドの場合は名前付きフィールド名、またはタプルの
/// `field_0`、`field_1` などの名前で借用アクセサーも生成します。
/// 列挙型にはバリアント名をすべて小文字にした(snake case ではない)接尾辞で
/// `new_<variant>`、`is_<variant>`、`as_<variant>` を生成します。
/// バリアントアクセサーは不一致なら `None`、ユニットなら `Some(())`、それ以外は
/// フィールド参照のタプルを返します。小文字化した名前は一意である必要があり、
/// 生成する名前を他のメソッドやフィールドアクセサーと衝突させないでください。
///
/// `#[value_object(validate = path, error = ErrorType)]` は `new` を `try_new`
/// (列挙型では `try_new_<variant>`)に置き換えます。両オプションの同時指定が必要です。
/// 検証関数は単一フィールドなら `&Inner`、それ以外なら `&Self` を受け取り、
/// `Result<(), ErrorType>` を返します。値を返す前に検証し、エラーを伝播します。
/// 検証関数のパニックは捕捉しません。検証付き構造体のフィールドは無制限の `pub` に
/// できませんが、制限付き公開、定義モジュール内の直接構築、列挙型のバリアントからは
/// 検証を迂回できます。
///
/// `#[value_object(serde)]` はコアの serde 再公開を使う直列化実装も生成します。
/// コアの `serde` feature を有効にしてください。単一フィールドは内包値、名前付き
/// 構造体は構造体、タプル構造体はタプル、列挙型は外部タグ形式で直列化します。
/// 単一フィールドのタプルバリアントは Serde の newtype 形式、その他はタプル形式です。
/// 逆直列化時も設定された検証を
/// 実行し、検証エラーを `value object validation failed` に変換します。
/// 直列化の生成はマクロクレートの feature ではなく、この属性で選択します。
/// 非対応の形状、重複・未知のオプション、コア依存の欠落はコンパイルエラーになります。
/// フィールド型は生成するトレイトの境界を満たす必要があります。
///
/// # Example / 使用例
///
/// ```rust
/// use ddd_toolkit_macro::ValueObject;
///
/// #[derive(ValueObject)]
/// #[value_object(validate = positive, error = &'static str)]
/// struct Quantity(u32);
///
/// fn positive(value: &u32) -> Result<(), &'static str> {
/// if *value > 0 { Ok(()) } else { Err("zero quantity") }
/// }
///
/// assert_eq!(Quantity::try_new(0), Err("zero quantity"));
/// assert_eq!(Quantity::try_new(2).unwrap().into_inner(), 2);
///
/// #[derive(ValueObject)]
/// enum Status { Pending, Ready(u32) }
/// let status = Status::new_ready(7);
/// assert_eq!(status.as_ready(), Some((&7,)));
/// assert!(!status.is_pending());
/// ```
/// **English:**<br>
/// Implements `ddd_toolkit_core::Entity`, a borrowed inherent `id()`
/// accessor, and `PartialEq`, `Eq`, and `Hash` using only the identifier field.
///
/// Requires a named-field struct with exactly one `#[entity(id)]` field. Other
/// fields do not participate in comparison or hashing; identifier types must
/// implement the corresponding traits. No constructor or identifier validation
/// is generated. Non-struct inputs, misplaced flags, missing or multiple identifier
/// fields, unknown options, and missing core dependencies cause compile errors.
///
/// **日本語:**<br>
/// `ddd_toolkit_core::Entity` と識別子を借用する固有の `id()`、
/// 識別子フィールドだけを使う `PartialEq`、`Eq`、`Hash` を実装します。
///
/// 名前付き構造体に `#[entity(id)]` フィールドがちょうど一つ必要です。
/// 他のフィールドは比較やハッシュに使いません。識別子型は対応するトレイトを
/// 実装する必要があります。コンストラクターや識別子の検証は生成しません。
/// 構造体以外、フラグの誤配置、識別子の欠落・複数指定、未知のオプション、
/// コア依存の欠落はコンパイルエラーになります。
///
/// # Example / 使用例
///
/// ```rust
/// use ddd_toolkit_macro::Entity;
///
/// #[derive(Entity)]
/// struct Order {
/// #[entity(id)]
/// id: u64,
/// total: u32,
/// }
/// let first = Order { id: 1, total: 10 };
/// let updated = Order { id: 1, total: 20 };
/// assert!(first == updated);
/// assert_eq!(updated.id(), &1);
/// ```
/// **English:**<br>
/// Implements the empty `ddd_toolkit_core::DomainEvent` marker for
/// a struct or enum, preserving its generic parameters and where clause.
///
/// Does not add methods, serialization, `Send`, or `Sync` bounds. Event contents
/// and delivery remain the caller's responsibility. Unions and missing core
/// dependencies produce compile errors.
///
/// **日本語:**<br>
/// 構造体または列挙型に、空の `ddd_toolkit_core::DomainEvent`
/// マーカーを実装し、ジェネリック引数と where 節を維持します。
///
/// メソッド、直列化、`Send`・`Sync` 境界は追加しません。イベントの内容と配信は
/// 呼び出し側が管理します。共用体やコア依存の欠落はコンパイルエラーになります。
///
/// # Example / 使用例
///
/// ```rust
/// use ddd_toolkit_macro::DomainEvent;
///
/// #[derive(DomainEvent)]
/// enum OrderEvent { Placed { order_id: u64 }, Cancelled }
/// fn accept_event(_: impl ddd_toolkit_core::DomainEvent) {}
/// accept_event(OrderEvent::Placed { order_id: 1 });
/// ```
/// **English:**<br>
/// Implements `ddd_toolkit_core::AggregateRoot` using a struct's
/// `#[aggregate(events)]` vector as its pending event queue.
///
/// Requires a named-field struct that already implements `ddd_toolkit_core::Entity`
/// (for example via [`Entity`]) and exactly one marked field spelled `Vec<Event>`
/// or `std::vec::Vec<Event>`. Type aliases and other vector paths are not accepted;
/// `Event` must implement `ddd_toolkit_core::DomainEvent` (see [`DomainEvent`]).
/// `record_event` appends with `Vec::push`, preserving insertion order, and may
/// allocate. `pull_events` moves out the vector with `core::mem::take`, leaving an
/// empty queue; repeated pulls return empty vectors until another event is recorded.
/// These are trait methods, not inherent methods; import the core trait to call
/// them. Both require exclusive mutable access, with no locking, event publication,
/// persistence, or domain-state update generated. Vector growth has the usual
/// allocation and capacity limits of `Vec::push`.
/// Unsupported shapes, missing or duplicate queues, unknown or valued flags,
/// missing trait implementations, and missing core dependencies fail to compile.
///
/// **日本語:**<br>
/// 構造体の `#[aggregate(events)]` ベクターを未処理イベントキュー
/// として `ddd_toolkit_core::AggregateRoot` を実装します。
///
/// `ddd_toolkit_core::Entity` を実装済みの名前付き構造体(例: [`Entity`] による導出)
/// と、`Vec<Event>` または `std::vec::Vec<Event>` と記述されたキューフィールドが
/// ちょうど一つ必要です。型エイリアスや他のベクターパスは受け付けません。
/// `Event` は `ddd_toolkit_core::DomainEvent` を実装する必要があります([`DomainEvent`])。
/// `record_event` は `Vec::push` で挿入順に追加し、メモリを確保する場合があります。
/// `pull_events` は `core::mem::take` でベクターを取り出し、キューを空にします。
/// 次の記録まで再度取り出しても空のベクターを返します。固有メソッドではなくトレイト
/// メソッドなので、呼び出すにはコアのトレイトをインポートしてください。
/// どちらも排他的な可変アクセスを要求し、ロック、イベント配信、永続化、ドメイン状態の
/// 更新は生成しません。キューの拡張には `Vec::push` と同じメモリ確保・容量制限があります。
/// 非対応の形状、キューの欠落・重複、未知または値付きフラグ、必要なトレイト実装や
/// コア依存の欠落はコンパイルエラーになります。
///
/// # Example / 使用例
///
/// ```rust
/// use ddd_toolkit_core::AggregateRoot as _;
/// use ddd_toolkit_macro::{AggregateRoot, DomainEvent, Entity};
///
/// #[derive(DomainEvent)]
/// struct Placed;
///
/// #[derive(Entity, AggregateRoot)]
/// struct Order {
/// #[entity(id)]
/// id: u64,
/// #[aggregate(events)]
/// events: Vec<Placed>,
/// }
/// let mut order = Order { id: 1, events: Vec::new() };
/// order.record_event(Placed);
/// assert_eq!(order.pull_events().len(), 1);
/// assert!(order.pull_events().is_empty());
/// ```