photon-backend 0.1.0

Photon publish/subscribe backend implementations and storage adapters
Documentation
//! Handler descriptor for `#[photon::subscribe]` inventory registration.

use std::future::Future;
use std::pin::Pin;

use photon_core::IdentityFactory;

use crate::error::Result;
use crate::models::Event;

/// Invokes a registered handler with reconstructed identity and the transport event.
///
/// The generated invoker reads `actor_json` / `payload_json` (and metadata) from `event`.
pub type HandlerInvoker = for<'a> fn(
    &'a dyn IdentityFactory,
    &'a Event,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'a>>;

/// Descriptor for a `#[photon::subscribe]` handler (inventory + executor dispatch).
#[derive(Clone, Copy)]
pub struct HandlerDescriptor {
    /// Topic this handler listens on.
    pub topic_name: &'static str,
    /// Durable subscription name for broadcast handlers (empty for group handlers).
    pub subscription_name: &'static str,
    /// Stable registry key (`{topic}:{subscription}` or `{topic}:group:{group}`).
    pub registry_key: &'static str,
    /// Async dispatch entry point generated by the proc macro.
    pub invoke: HandlerInvoker,
    /// Consumer group id when load-balanced (mutually exclusive with durable name).
    pub consumer_group: Option<&'static str>,
    /// Override virtual shard count for group handlers.
    pub group_shard_count: Option<u32>,
}

impl HandlerDescriptor {
    /// Create a broadcast handler descriptor for inventory submission.
    pub const fn new(
        topic_name: &'static str,
        subscription_name: &'static str,
        registry_key: &'static str,
        invoke: HandlerInvoker,
    ) -> Self {
        Self {
            topic_name,
            subscription_name,
            registry_key,
            invoke,
            consumer_group: None,
            group_shard_count: None,
        }
    }

    /// Create a consumer-group handler descriptor.
    pub const fn new_group(
        topic_name: &'static str,
        consumer_group: &'static str,
        group_shard_count: Option<u32>,
        registry_key: &'static str,
        invoke: HandlerInvoker,
    ) -> Self {
        Self {
            topic_name,
            subscription_name: "",
            registry_key,
            invoke,
            consumer_group: Some(consumer_group),
            group_shard_count,
        }
    }

    /// Whether this handler uses consumer-group delivery.
    #[must_use]
    pub const fn is_consumer_group(&self) -> bool {
        self.consumer_group.is_some()
    }
}

crate::inventory::collect!(HandlerDescriptor);

impl quark::Registrable for HandlerDescriptor {
    fn registry_key(&self) -> &str {
        self.registry_key
    }
}