Coverage Report

Created: 2026-01-30 06:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}