Skip to main content

ClosureHandler

Struct ClosureHandler 

Source
#[non_exhaustive]
pub struct ClosureHandler<B: Send + Sync + 'static, C: Clone + Send + 'static> { /* private fields */ }
Expand description

A JmapHandler that wraps an async closure over a shared backend and forwards CallerCtx to it.

Use this when your handler closures need per-request context — for example, an auth identity that controls which data the handler can access. Closures that don’t need the context can simply ignore the ctx parameter.

§Usage

use jmap_server::{ClosureHandler, Dispatcher};
use std::sync::Arc;

#[derive(Clone)]
struct AuthCtx { user_id: String }

let handler: Arc<ClosureHandler<MyBackend, AuthCtx>> =
    Arc::new(ClosureHandler::new(
        Arc::new(my_backend),
        |b, call_id, args, ctx| {
            Box::pin(async move {
                // ctx.user_id is available here
                handle_something(&*b, args, &ctx.user_id).await
            })
        },
    ));

let mut dispatcher: Dispatcher<AuthCtx> = Dispatcher::new();
dispatcher.register("MyMethod/get", handler);

A JmapHandler handle wrapping a shared backend + an async closure. Construct via ClosureHandler::new — the fields are crate-private (bd:JMAP-jfia.5) to keep the handle opaque, prevent post-construction hot-swap of the closure or backend, and let the constructor remain the sole site that enforces invariants when future fields (per-handler tracing context, metrics handle, etc.) are added.

Implementations§

Source§

impl<B: Send + Sync + 'static, C: Clone + Send + 'static> ClosureHandler<B, C>

Source

pub fn new<F>(backend: Arc<B>, call_fn: F) -> Self
where F: Fn(Arc<B>, String, Value, C) -> HandlerFuture + Send + Sync + 'static,

Construct a ClosureHandler wrapping a shared backend and an async closure (bd:JMAP-wlip.17).

This is the supported construction path. The struct is #[non_exhaustive] so future fields (per-handler tracing context, metrics handle, timeout, etc.) can be added without a major-version bump — external callers MUST go through new rather than struct-literal syntax.

The call_fn parameter is generic over F: Fn(...) + Send + Sync + 'static (bd:JMAP-jfia.40), so callers can pass a closure directly without wrapping it in Box::new. Existing callers that already wrap in Box::new(...) continue to compile unchanged: Box<dyn Fn(...) + Send + Sync + 'static> itself implements Fn(...) via the blanket impl<F: Fn(...)> Fn(...) for Box<F>, so the boxed form satisfies the generic bound. Internally, the closure is boxed once at construction and stored as Box<BackendCallFn<B, C>>.

Trait Implementations§

Source§

impl<B: Send + Sync + 'static, C: Clone + Send + 'static> JmapHandler<C> for ClosureHandler<B, C>

Source§

fn call( &self, _method: String, call_id: String, args: Value, caller: C, ) -> HandlerFuture

method is the registered method name for this call. A single handler instance may be registered under multiple names (e.g. both "Foo/get" and "Bar/get"); this parameter lets the handler distinguish between them. Read more

Auto Trait Implementations§

§

impl<B, C> !RefUnwindSafe for ClosureHandler<B, C>

§

impl<B, C> !UnwindSafe for ClosureHandler<B, C>

§

impl<B, C> Freeze for ClosureHandler<B, C>

§

impl<B, C> Send for ClosureHandler<B, C>

§

impl<B, C> Sync for ClosureHandler<B, C>

§

impl<B, C> Unpin for ClosureHandler<B, C>

§

impl<B, C> UnsafeUnpin for ClosureHandler<B, C>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.