restate-sdk 0.11.0

Restate SDK for Rust
Documentation
use crate::endpoint;
use crate::endpoint::BoxedService;
use std::future::Future;

/// Trait representing a Restate service.
///
/// This is used by codegen.
pub trait Service {
    type Future: Future<Output = Result<(), endpoint::Error>> + Send + 'static;

    /// Handle an incoming request.
    fn handle(&self, req: endpoint::ContextInternal) -> Self::Future;
}

/// Trait representing a discoverable Restate service.
///
/// This is used by codegen.
pub trait Discoverable {
    fn discover() -> crate::discovery::Service;
}

/// A fully-composed service, ready to be bound to an [`Endpoint`](crate::endpoint::Endpoint) via
/// [`Endpoint::builder().bind(..)`](crate::endpoint::Builder::bind).
///
/// You usually don't construct this directly: the `#[restate_sdk::service]`/`#[object]`/`#[workflow]`
/// macros make the annotated type implement [`IntoServiceDefinition`], so you can `bind` the value
/// directly. Use [`ServiceDefinition::options`] to attach [`ServiceOptions`](crate::endpoint::ServiceOptions)
/// (timeouts, retention, retry policy, ...) before binding.
pub struct ServiceDefinition {
    pub(crate) discovery: crate::discovery::Service,
    pub(crate) dispatcher: BoxedService,
}

impl ServiceDefinition {
    /// Apply [`ServiceOptions`](crate::endpoint::ServiceOptions) (timeouts, retention, per-handler
    /// options, ...) to this definition, then `bind` it.
    pub fn options(mut self, options: crate::endpoint::ServiceOptions) -> Self {
        self.discovery.apply_options(options);
        self
    }
}

/// Anything that can be turned into a [`ServiceDefinition`] for
/// [`Endpoint::builder().bind(..)`](crate::endpoint::Builder::bind).
///
/// Implemented for [`ServiceDefinition`] and for the types generated by the
/// `#[restate_sdk::service]`/`#[object]`/`#[workflow]` macros (both the struct-based API and the
/// deprecated trait-based `.serve()` values).
pub trait IntoServiceDefinition {
    fn into_service_definition(self) -> ServiceDefinition;
}

impl IntoServiceDefinition for ServiceDefinition {
    fn into_service_definition(self) -> ServiceDefinition {
        self
    }
}

/// Codegen-facing support surface. Referenced by the code the service macros generate; not part of
/// the public API.
#[doc(hidden)]
pub mod macro_support {
    use super::{Service, ServiceDefinition};
    use crate::endpoint::{self, BoxedService};
    use futures::future::BoxFuture;

    pub type ServiceBoxFuture = BoxFuture<'static, Result<(), endpoint::Error>>;

    /// Build a [`ServiceDefinition`] from a generated dispatcher and the discovery manifest produced
    /// by the service's [`Discoverable`](super::Discoverable) impl. Used by the `IntoServiceDefinition`
    /// impls the service macros emit.
    pub fn service_definition<S>(
        dispatcher: S,
        discovery: crate::discovery::Service,
    ) -> ServiceDefinition
    where
        S: Service<Future = ServiceBoxFuture> + Send + Sync + 'static,
    {
        ServiceDefinition {
            discovery,
            dispatcher: BoxedService::new(dispatcher),
        }
    }
}