actor_sample/product_actor/
entity.rs

1//! Entity trait implementation for the Product resource type.
2//!
3//! This module contains the [`ActorEntity`] trait implementation
4//! that enables [`Product`] to be managed by the generic [`actor_framework::ResourceActor`].
5//!
6//! Includes support for custom actions like stock checking and reservation.
7//!
8//! See the trait implementation on [`Product`] for method documentation.
9
10use crate::model::{Product, ProductCreate, ProductId, ProductUpdate};
11use crate::product_actor::{ProductAction, ProductActionResult, ProductError};
12use actor_framework::ActorEntity;
13use async_trait::async_trait;
14
15/// Marker constant to ensure module documentation is rendered.
16#[doc(hidden)]
17/// Marker constant to verify ActorEntity trait implementation exists at compile time.
18#[allow(dead_code)]
19pub const ENTITY_IMPL_PRESENT: bool = true;
20
21#[async_trait]
22impl ActorEntity for Product {
23    type Id = ProductId;
24    type Create = ProductCreate;
25    type Update = ProductUpdate;
26    type Action = ProductAction;
27    type ActionResult = ProductActionResult;
28    type Context = ();
29    type Error = ProductError;
30
31    // fn id(&self) -> &String { &self.id }
32
33    /// Creates a new Product from creation parameters.
34    fn from_create_params(id: ProductId, params: ProductCreate) -> Result<Self, Self::Error> {
35        Ok(Product::new(id, params.name, params.price, params.quantity))
36    }
37
38    /// Handles updates to the Product entity.
39    ///
40    /// # Fields Updated
41    /// - `price`: Product price
42    /// - `quantity`: Available stock quantity
43    async fn on_update(
44        &mut self,
45        update: ProductUpdate,
46        _ctx: &Self::Context,
47    ) -> Result<(), Self::Error> {
48        if let Some(price) = update.price {
49            self.price = price;
50        }
51        if let Some(quantity) = update.quantity {
52            self.quantity = quantity;
53        }
54        Ok(())
55    }
56
57    /// Handles custom actions for the Product entity.
58    ///
59    /// # Actions
60    /// - `CheckStock`: Returns true if requested quantity is available
61    /// - `ReserveStock`: Decrements stock if available, returns true on success
62    async fn handle_action(
63        &mut self,
64        action: ProductAction,
65        _ctx: &Self::Context,
66    ) -> Result<ProductActionResult, Self::Error> {
67        match action {
68            ProductAction::CheckStock => Ok(ProductActionResult::CheckStock(self.quantity)),
69            ProductAction::ReserveStock(quantity) => {
70                if self.quantity >= quantity {
71                    self.quantity -= quantity;
72                    Ok(ProductActionResult::ReserveStock(()))
73                } else {
74                    Err(ProductError::InsufficientStock {
75                        requested: quantity,
76                        available: self.quantity,
77                    })
78                }
79            }
80        }
81    }
82}