Skip to main content

medi_rs/handler/
static_handler.rs

1use core::future::Future;
2
3/// Type-level dependency declaration for a [`StaticHandler`].
4#[doc(hidden)]
5pub struct Dependency<T, I>(core::marker::PhantomData<fn() -> (T, I)>);
6
7/// A statically dispatched async handler function.
8pub trait StaticHandler<R, Req, Dependencies>: Clone {
9    type Response;
10    type Error;
11
12    fn handle(
13        self,
14        resources: &R,
15        value: Req,
16    ) -> impl Future<Output = core::result::Result<Self::Response, Self::Error>> + Send;
17}
18
19#[cfg(test)]
20mod tests {
21    use super::StaticHandler;
22    use crate::{Dependency, tlist::Here};
23    use alloc::{format, string::String};
24
25    #[derive(Clone)]
26    struct Prefix(&'static str);
27    struct Greet(&'static str);
28    #[derive(Debug, Eq, PartialEq)]
29    struct HandlerError;
30
31    async fn greet(prefix: Prefix, command: Greet) -> Result<String, HandlerError> {
32        Ok(format!("{} {}", prefix.0, command.0))
33    }
34
35    async fn invoke<F, R, Req, Dependencies>(handler: F, resources: &R, request: Req) -> Result<F::Response, F::Error>
36    where
37        F: StaticHandler<R, Req, Dependencies>,
38    {
39        handler.handle(resources, request).await
40    }
41
42    #[tokio::test]
43    async fn invokes_a_handler_with_a_typed_resource() {
44        let resources = (Prefix("Hello"), ());
45        assert_eq!(
46            invoke::<_, _, _, (Dependency<Prefix, Here>,)>(greet, &resources, Greet("Ada"))
47                .await
48                .unwrap(),
49            "Hello Ada"
50        );
51    }
52}