Skip to main content

ValueObject

Derive Macro ValueObject 

Source
#[derive(ValueObject)]
{
    // Attributes available to this derive:
    #[value_object]
}
Expand description

English:
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.

日本語:
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 / 使用例

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());