Skip to main content

entity

Attribute Macro entity 

Source
#[entity]
Expand description

Mark a struct as a DDD entity / aggregate root.

The macro guarantees that the annotated struct has the two fields every eventide_domain::entity::Entity implementation needs:

  • id: <IdType> — the entity’s identity.
  • version: ::eventide_domain::value_object::Version — the optimistic- concurrency version used during event-sourced rehydration.

If either field is missing it is inserted; if both are present they are repositioned so they appear at the top of the struct (in that order), keeping the layout consistent across all entities. The macro then generates an impl Entity for ... block exposing new, id and version.

A normalised derive attribute is also produced. By default this includes Debug, Default, serde::Serialize and serde::Deserialize; any derives the user already wrote are merged in (de-duplicated against the standard set, e.g. Serialize and serde::Serialize collapse).

§Attribute arguments

#[entity(id = <Type>, debug = <bool>)]

  • id — type used for the id field. Defaults to String.
  • debug — when false the macro will not derive Debug, so callers can provide a custom Debug impl. Defaults to true.

Both keys are optional and may appear in any order.

§Examples

Minimal usage with a String identifier:

use eventide_macros::entity;

#[entity]
struct Account {
    name: String,
    balance: i64,
}

With a custom newtype identifier:

use eventide_macros::{entity, entity_id};
use uuid::Uuid;

#[entity_id]
struct UserId(Uuid);

#[entity(id = UserId)]
struct User {
    name: String,
}

Suppressing the derived Debug to provide a custom impl:

use eventide_macros::entity;

#[entity(id = String, debug = false)]
struct Secret {
    value: String,
}

impl std::fmt::Debug for Secret {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("Secret").field("value", &"<redacted>").finish()
    }
}