ActorEntity

Trait ActorEntity 

Source
pub trait ActorEntity:
    Clone
    + Send
    + Sync
    + 'static {
    type Id: Eq + Hash + Clone + Send + Sync + Display + Debug + From<u32>;
    type Create: Send + Sync + Debug;
    type Update: Send + Sync + Debug;
    type Action: Send + Sync + Debug;
    type ActionResult: Send + Sync + Debug;
    type Context: Send + Sync;
    type Error: Error + Send + Sync + 'static;

    // Required methods
    fn from_create_params(
        id: Self::Id,
        params: Self::Create,
    ) -> Result<Self, Self::Error>;
    fn on_update<'life0, 'life1, 'async_trait>(
        &'life0 mut self,
        update: Self::Update,
        _ctx: &'life1 Self::Context,
    ) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn handle_action<'life0, 'life1, 'async_trait>(
        &'life0 mut self,
        action: Self::Action,
        _ctx: &'life1 Self::Context,
    ) -> Pin<Box<dyn Future<Output = Result<Self::ActionResult, Self::Error>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;

    // Provided methods
    fn on_create<'life0, 'life1, 'async_trait>(
        &'life0 mut self,
        _ctx: &'life1 Self::Context,
    ) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait { ... }
    fn on_delete<'life0, 'life1, 'async_trait>(
        &'life0 self,
        _ctx: &'life1 Self::Context,
    ) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait { ... }
}
Expand description

Trait that any resource entity must implement to be managed by ResourceActor.

§Architecture Note

By defining a contract (ActorEntity) that all our resource types (User, Product, Order) must satisfy, we can write the ResourceActor logic once and reuse it everywhere.

§Async & Context

This trait is #[async_trait] to allow asynchronous operations in hooks (e.g., calling other actors). It also defines a Context type, which is injected into every hook. This allows “Late Binding” of dependencies (passing clients to run() instead of new()).

Required Associated Types§

Source

type Id: Eq + Hash + Clone + Send + Sync + Display + Debug + From<u32>

The unique identifier for this entity (e.g., String, Uuid, u64). Must be convertible from u32 for automatic ID generation.

Source

type Create: Send + Sync + Debug

The data required to create a new instance (DTO - Data Transfer Object).

Source

type Update: Send + Sync + Debug

The data required to update an existing instance.

Source

type Action: Send + Sync + Debug

Enum representing resource-specific operations (e.g., ReserveStock).

Source

type ActionResult: Send + Sync + Debug

The result type returned by custom actions.

Source

type Context: Send + Sync

The runtime context (dependencies) injected into the actor. Use () if no dependencies are needed.

Source

type Error: Error + Send + Sync + 'static

The error type for this entity. Must implement std::error::Error for proper error propagation.

§Design Note: Error Granularity

The framework enforces a Per-Actor Error Type (one enum for the whole actor) rather than Per-Message Error Types (a specific error for each action).

Why?

  • Simplicity: Reduces boilerplate. You don’t need to define 10 different error enums for 10 actions.
  • Ergonomics: Clients deal with a single UserError type, making pattern matching easier.

Trade-off: This means UserError must be the union of all possible errors. If ActionA can only fail with ErrorX, but ActionB can fail with ErrorY, the return type for both is Result<..., UserError>, which technically allows ErrorY to be returned from ActionA. In practice, this theoretical loss of precision is worth the massive reduction in code complexity.

Required Methods§

Source

fn from_create_params( id: Self::Id, params: Self::Create, ) -> Result<Self, Self::Error>

Construct the full Entity from the ID and Payload. This is called synchronously before on_create.

Source

fn on_update<'life0, 'life1, 'async_trait>( &'life0 mut self, update: Self::Update, _ctx: &'life1 Self::Context, ) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Called when an update request is received.

Source

fn handle_action<'life0, 'life1, 'async_trait>( &'life0 mut self, action: Self::Action, _ctx: &'life1 Self::Context, ) -> Pin<Box<dyn Future<Output = Result<Self::ActionResult, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Handle a custom resource-specific action.

Provided Methods§

Source

fn on_create<'life0, 'life1, 'async_trait>( &'life0 mut self, _ctx: &'life1 Self::Context, ) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Called immediately after the entity is created and initialized. Use this hook to perform validation or side effects (e.g., checking other actors).

Source

fn on_delete<'life0, 'life1, 'async_trait>( &'life0 self, _ctx: &'life1 Self::Context, ) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Called immediately before the entity is removed from the system.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§