/rust/registry/src/index.crates.io-1949cf8c6b5b557f/hyper-1.8.1/src/service/service.rs
Line | Count | Source |
1 | | use 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 an 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. |
20 | | /// |
21 | | /// # Utilities |
22 | | /// |
23 | | /// The [`hyper-util`][util] crate provides facilities to bridge this trait to |
24 | | /// other libraries, such as [`tower`][tower], which might provide their |
25 | | /// own `Service` variants. |
26 | | /// |
27 | | /// See [`hyper_util::service`][util-service] for more information. |
28 | | /// |
29 | | /// [tower]: https://docs.rs/tower |
30 | | /// [util]: https://docs.rs/hyper-util |
31 | | /// [util-service]: https://docs.rs/hyper-util/latest/hyper_util/service/index.html |
32 | | pub trait Service<Request> { |
33 | | /// Responses given by the service. |
34 | | type Response; |
35 | | |
36 | | /// Errors produced by the service. |
37 | | /// |
38 | | /// Note: Returning an `Error` to a hyper server, the behavior depends on the |
39 | | /// protocol. In most cases, hyper will cause the connection to be abruptly aborted. |
40 | | /// It will abort the request however the protocol allows, either with some sort of RST_STREAM, |
41 | | /// or killing the connection if that doesn't exist. |
42 | | type Error; |
43 | | |
44 | | /// The future response value. |
45 | | type Future: Future<Output = Result<Self::Response, Self::Error>>; |
46 | | |
47 | | /// Process the request and return the response asynchronously. |
48 | | /// `call` takes `&self` instead of `mut &self` because: |
49 | | /// - It prepares the way for async fn, |
50 | | /// since then the future only borrows `&self`, and thus a Service can concurrently handle |
51 | | /// multiple outstanding requests at once. |
52 | | /// - It's clearer that Services can likely be cloned. |
53 | | /// - To share state across clones, you generally need `Arc<Mutex<_>>` |
54 | | /// That means you're not really using the `&mut self` and could do with a `&self`. |
55 | | /// The discussion on this is here: <https://github.com/hyperium/hyper/issues/3040> |
56 | | fn call(&self, req: Request) -> Self::Future; |
57 | | } |
58 | | |
59 | | impl<Request, S: Service<Request> + ?Sized> Service<Request> for &'_ S { |
60 | | type Response = S::Response; |
61 | | type Error = S::Error; |
62 | | type Future = S::Future; |
63 | | |
64 | | #[inline] |
65 | 0 | fn call(&self, req: Request) -> Self::Future { |
66 | 0 | (**self).call(req) |
67 | 0 | } |
68 | | } |
69 | | |
70 | | impl<Request, S: Service<Request> + ?Sized> Service<Request> for &'_ mut S { |
71 | | type Response = S::Response; |
72 | | type Error = S::Error; |
73 | | type Future = S::Future; |
74 | | |
75 | | #[inline] |
76 | 0 | fn call(&self, req: Request) -> Self::Future { |
77 | 0 | (**self).call(req) |
78 | 0 | } |
79 | | } |
80 | | |
81 | | impl<Request, S: Service<Request> + ?Sized> Service<Request> for Box<S> { |
82 | | type Response = S::Response; |
83 | | type Error = S::Error; |
84 | | type Future = S::Future; |
85 | | |
86 | | #[inline] |
87 | 0 | fn call(&self, req: Request) -> Self::Future { |
88 | 0 | (**self).call(req) |
89 | 0 | } |
90 | | } |
91 | | |
92 | | impl<Request, S: Service<Request> + ?Sized> Service<Request> for std::rc::Rc<S> { |
93 | | type Response = S::Response; |
94 | | type Error = S::Error; |
95 | | type Future = S::Future; |
96 | | |
97 | | #[inline] |
98 | 0 | fn call(&self, req: Request) -> Self::Future { |
99 | 0 | (**self).call(req) |
100 | 0 | } |
101 | | } |
102 | | |
103 | | impl<Request, S: Service<Request> + ?Sized> Service<Request> for std::sync::Arc<S> { |
104 | | type Response = S::Response; |
105 | | type Error = S::Error; |
106 | | type Future = S::Future; |
107 | | |
108 | | #[inline] |
109 | 0 | fn call(&self, req: Request) -> Self::Future { |
110 | 0 | (**self).call(req) |
111 | 0 | } |
112 | | } |