use crate::reply::Reply;
use crate::request::{OwnedRequest, Request};
use crate::types::Response;
use std::sync::Arc;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[must_use]
pub enum Outcome {
Done,
Deferred,
}
pub trait Service: Send + Sync + 'static {
fn call(&self, req: &mut Request<'_>, reply: Reply<'_>) -> Outcome;
#[doc(hidden)]
fn watch(&self, req: &Request<'_>) -> Option<WatchRef<'_>> {
let _ = req;
None
}
}
#[doc(hidden)]
#[derive(Debug)]
pub struct WatchRef<'a> {
pub(crate) watch: &'a Arc<crate::watchdog::Watch>,
pub(crate) stalls: Option<u32>,
pub(crate) name: &'a str,
}
impl<F> Service for F
where
F: Fn(&mut Request<'_>, Reply<'_>) -> Outcome + Send + Sync + 'static,
{
fn call(&self, req: &mut Request<'_>, reply: Reply<'_>) -> Outcome {
self(req, reply)
}
}
impl<S: Service + ?Sized> Service for Arc<S> {
fn call(&self, req: &mut Request<'_>, reply: Reply<'_>) -> Outcome {
(**self).call(req, reply)
}
fn watch(&self, req: &Request<'_>) -> Option<WatchRef<'_>> {
(**self).watch(req)
}
}
pub fn blocking<F>(f: F) -> Blocking<F>
where
F: Fn(OwnedRequest) -> Response + Send + Sync + 'static,
{
Blocking { f: Arc::new(f) }
}
pub struct Blocking<F> {
f: Arc<F>,
}
impl<F> std::fmt::Debug for Blocking<F> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("Blocking")
}
}
impl<F> Service for Blocking<F>
where
F: Fn(OwnedRequest) -> Response + Send + Sync + 'static,
{
fn call(&self, req: &mut Request<'_>, reply: Reply<'_>) -> Outcome {
let f = self.f.clone();
reply.blocking(req, move |r| f(r))
}
}