actr-framework 0.2.1

Actor-RTC framework core (stub for code generation testing)
Documentation
//! MessageDispatcher trait - Message routing and dispatching

use actr_protocol::{ActorResult, RpcEnvelope};
use async_trait::async_trait;
use bytes::Bytes;

use crate::{Context, Workload};

/// MessageDispatcher - Message dispatcher interface
///
/// Responsible for routing incoming message envelopes to corresponding handler methods.
///
/// # Design Characteristics
///
/// - **Static routing**: Implemented via compile-time match statements, no runtime lookup overhead
/// - **Zero-sized type (ZST)**: Router itself occupies no memory
/// - **Code generation**: Implementation is auto-generated by `actr-cli` codegen
///
/// # Code Generation Example
///
/// ```rust,ignore
/// // Generated by code generator
/// pub struct EchoServiceRouter<T: EchoServiceHandler>(PhantomData<T>);
///
/// #[async_trait]
/// impl<T: EchoServiceHandler> MessageDispatcher for EchoServiceRouter<T> {
///     type Workload = EchoServiceWorkload<T>;
///
///     async fn dispatch<C: Context>(
///         workload: &Self::Workload,
///         envelope: RpcEnvelope,
///         ctx: &C,
///     ) -> ActorResult<Bytes> {
///         match envelope.route_key.as_str() {
///             "echo.EchoService.Echo" => {
///                 let req = EchoRequest::decode(&*envelope.payload)?;
///                 let resp = workload.0.echo(req, ctx).await?;
///                 Ok(resp.encode_to_vec().into())
///             }
///             _ => Err(ProtocolError::Actr(ActrError::UnknownRoute {
///                 route_key: envelope.route_key.to_string()
///             }))
///         }
///     }
/// }
/// ```
// Same cross-target rationale as `Context` / `Workload`: `?Send` on wasm32,
// native default `Send` auto trait elsewhere. `MaybeSendSync` silently
// re-adds `Send + Sync` on native.
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
pub trait MessageDispatcher: crate::MaybeSendSync + 'static {
    /// Associated Workload type
    type Workload: Workload<Dispatcher = Self>;

    /// Dispatch message to corresponding handler method and execute full request-response cycle
    ///
    /// # Responsibilities
    ///
    /// 1. **Routing**: Select handler method based on `envelope.route_key`
    /// 2. **Decoding**: Deserialize payload into concrete message type
    /// 3. **Dispatching**: Invoke workload's business logic method
    /// 4. **Encoding**: Serialize response into bytes
    ///
    /// # Parameters
    ///
    /// - `workload`: Workload instance (contains user business logic)
    /// - `envelope`: Message envelope (contains route_key and payload)
    /// - `ctx`: Execution context (generic, supports any Context implementation)
    ///
    /// # Returns
    ///
    /// Returns serialized response bytes
    async fn dispatch<C: Context>(
        workload: &Self::Workload,
        envelope: RpcEnvelope,
        ctx: &C,
    ) -> ActorResult<Bytes>;
}