hyper/service/service.rs
1use std::future::Future;
2
3/// An asynchronous function from a `Request` to a `Response`.
4///
5/// The `Service` trait is a simplified interface making it easy to write
6/// network applications in a modular and reusable way, decoupled from the
7/// underlying protocol.
8///
9/// # Functional
10///
11/// A `Service` is a function of a `Request`. It immediately returns a
12/// `Future` representing the eventual completion of processing the
13/// request. The actual request processing may happen at any time in the
14/// future, on any thread or executor. The processing may depend on calling
15/// other services. At some point in the future, the processing will complete,
16/// and the `Future` will resolve to a response or error.
17///
18/// At a high level, the `Service::call` function represents an RPC request. The
19/// `Service` value can be a server or a client.
20pub trait Service<Request> {
21 /// Responses given by the service.
22 type Response;
23
24 /// Errors produced by the service.
25 type Error;
26
27 /// The future response value.
28 type Future: Future<Output = Result<Self::Response, Self::Error>>;
29
30 /// Process the request and return the response asynchronously.
31 /// `call` takes `&self` instead of `mut &self` because:
32 /// - It prepares the way for async fn,
33 /// since then the future only borrows `&self`, and thus a Service can concurrently handle
34 /// multiple outstanding requests at once.
35 /// - It's clearer that Services can likely be cloned
36 /// - To share state across clones, you generally need `Arc<Mutex<_>>`
37 /// That means you're not really using the `&mut self` and could do with a `&self`.
38 /// The discussion on this is here: <https://github.com/hyperium/hyper/issues/3040>
39 fn call(&self, req: Request) -> Self::Future;
40}
41
42impl<Request, S: Service<Request> + ?Sized> Service<Request> for &'_ S {
43 type Response = S::Response;
44 type Error = S::Error;
45 type Future = S::Future;
46
47 #[inline]
48 fn call(&self, req: Request) -> Self::Future {
49 (**self).call(req)
50 }
51}
52
53impl<Request, S: Service<Request> + ?Sized> Service<Request> for &'_ mut S {
54 type Response = S::Response;
55 type Error = S::Error;
56 type Future = S::Future;
57
58 #[inline]
59 fn call(&self, req: Request) -> Self::Future {
60 (**self).call(req)
61 }
62}
63
64impl<Request, S: Service<Request> + ?Sized> Service<Request> for Box<S> {
65 type Response = S::Response;
66 type Error = S::Error;
67 type Future = S::Future;
68
69 #[inline]
70 fn call(&self, req: Request) -> Self::Future {
71 (**self).call(req)
72 }
73}
74
75impl<Request, S: Service<Request> + ?Sized> Service<Request> for std::rc::Rc<S> {
76 type Response = S::Response;
77 type Error = S::Error;
78 type Future = S::Future;
79
80 #[inline]
81 fn call(&self, req: Request) -> Self::Future {
82 (**self).call(req)
83 }
84}
85
86impl<Request, S: Service<Request> + ?Sized> Service<Request> for std::sync::Arc<S> {
87 type Response = S::Response;
88 type Error = S::Error;
89 type Future = S::Future;
90
91 #[inline]
92 fn call(&self, req: Request) -> Self::Future {
93 (**self).call(req)
94 }
95}