tarpc-cat 0.1.0

RPC framework built on comp-cat-rs: typed effects, no async, categorical foundations
Documentation
//! Service trait for defining RPC handlers.
//!
//! A [`Serve`] implementation defines the request/response types
//! and the handler logic for a single RPC service.  The handler
//! returns an [`Io`] producing the response, keeping side effects
//! lazy and composable.
//!
//! [`Io`]: comp_cat_rs::effect::io::Io
//!
//! # Examples
//!
//! ```rust,ignore
//! use tarpc_cat::serve::Serve;
//! use tarpc_cat::error::Error;
//! use comp_cat_rs::effect::io::Io;
//! use serde::{Serialize, Deserialize};
//!
//! #[derive(Serialize, Deserialize)]
//! enum MathRequest { Add(i32, i32) }
//!
//! #[derive(Serialize, Deserialize)]
//! enum MathResponse { Sum(i32) }
//!
//! #[derive(Clone)]
//! struct MathService;
//!
//! impl Serve for MathService {
//!     type Request = MathRequest;
//!     type Response = MathResponse;
//!
//!     fn handle(&self, request: MathRequest) -> Io<Error, MathResponse> {
//!         match request {
//!             MathRequest::Add(a, b) => Io::pure(MathResponse::Sum(a + b)),
//!         }
//!     }
//! }
//! ```

use comp_cat_rs::effect::io::Io;
use serde::de::DeserializeOwned;
use serde::Serialize;

use crate::error::Error;

/// An RPC service handler.
///
/// Implementors define [`Request`](Serve::Request) and
/// [`Response`](Serve::Response) types plus a [`handle`](Serve::handle)
/// method that processes a request and returns an [`Io`] producing
/// the response.
///
/// [`Clone`] is required because the server clones the service for
/// each connection thread.  [`Send`] and `'static` are required
/// for thread safety.
pub trait Serve: Clone + Send + 'static {
    /// The request type, deserialized from the client envelope payload.
    type Request: DeserializeOwned + Send + 'static;

    /// The response type, serialized into the server envelope payload.
    type Response: Serialize + Send + 'static;

    /// Handle a single request.
    ///
    /// Returns an [`Io`] that, when run, produces the response.
    /// Pure handlers can use [`Io::pure`]; effectful handlers
    /// use [`Io::suspend`].
    ///
    /// # Errors
    ///
    /// The returned [`Io`] may fail with an [`Error`] which will
    /// be sent back to the client as an error envelope.
    fn handle(&self, request: Self::Request) -> Io<Error, Self::Response>;
}