summaryrefslogtreecommitdiff
path: root/vendor/hyper/src/service/service.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/hyper/src/service/service.rs')
-rw-r--r--vendor/hyper/src/service/service.rs100
1 files changed, 100 insertions, 0 deletions
diff --git a/vendor/hyper/src/service/service.rs b/vendor/hyper/src/service/service.rs
new file mode 100644
index 00000000..42c18e72
--- /dev/null
+++ b/vendor/hyper/src/service/service.rs
@@ -0,0 +1,100 @@
+use std::future::Future;
+
+/// An asynchronous function from a `Request` to a `Response`.
+///
+/// The `Service` trait is a simplified interface making it easy to write
+/// network applications in a modular and reusable way, decoupled from the
+/// underlying protocol.
+///
+/// # Functional
+///
+/// A `Service` is a function of a `Request`. It immediately returns a
+/// `Future` representing the eventual completion of processing the
+/// request. The actual request processing may happen at any time in the
+/// future, on any thread or executor. The processing may depend on calling
+/// other services. At some point in the future, the processing will complete,
+/// and the `Future` will resolve to a response or error.
+///
+/// At a high level, the `Service::call` function represents an RPC request. The
+/// `Service` value can be a server or a client.
+pub trait Service<Request> {
+ /// Responses given by the service.
+ type Response;
+
+ /// Errors produced by the service.
+ ///
+ /// Note: Returning an `Error` to a hyper server, the behavior depends on the
+ /// protocol. In most cases, hyper will cause the connection to be abruptly aborted.
+ /// It will abort the request however the protocol allows, either with some sort of RST_STREAM,
+ /// or killing the connection if that doesn't exist.
+ type Error;
+
+ /// The future response value.
+ type Future: Future<Output = Result<Self::Response, Self::Error>>;
+
+ /// Process the request and return the response asynchronously.
+ /// `call` takes `&self` instead of `mut &self` because:
+ /// - It prepares the way for async fn,
+ /// since then the future only borrows `&self`, and thus a Service can concurrently handle
+ /// multiple outstanding requests at once.
+ /// - It's clearer that Services can likely be cloned
+ /// - To share state across clones, you generally need `Arc<Mutex<_>>`
+ /// That means you're not really using the `&mut self` and could do with a `&self`.
+ /// The discussion on this is here: <https://github.com/hyperium/hyper/issues/3040>
+ fn call(&self, req: Request) -> Self::Future;
+}
+
+impl<Request, S: Service<Request> + ?Sized> Service<Request> for &'_ S {
+ type Response = S::Response;
+ type Error = S::Error;
+ type Future = S::Future;
+
+ #[inline]
+ fn call(&self, req: Request) -> Self::Future {
+ (**self).call(req)
+ }
+}
+
+impl<Request, S: Service<Request> + ?Sized> Service<Request> for &'_ mut S {
+ type Response = S::Response;
+ type Error = S::Error;
+ type Future = S::Future;
+
+ #[inline]
+ fn call(&self, req: Request) -> Self::Future {
+ (**self).call(req)
+ }
+}
+
+impl<Request, S: Service<Request> + ?Sized> Service<Request> for Box<S> {
+ type Response = S::Response;
+ type Error = S::Error;
+ type Future = S::Future;
+
+ #[inline]
+ fn call(&self, req: Request) -> Self::Future {
+ (**self).call(req)
+ }
+}
+
+impl<Request, S: Service<Request> + ?Sized> Service<Request> for std::rc::Rc<S> {
+ type Response = S::Response;
+ type Error = S::Error;
+ type Future = S::Future;
+
+ #[inline]
+ fn call(&self, req: Request) -> Self::Future {
+ (**self).call(req)
+ }
+}
+
+impl<Request, S: Service<Request> + ?Sized> Service<Request> for std::sync::Arc<S> {
+ type Response = S::Response;
+ type Error = S::Error;
+ type Future = S::Future;
+
+ #[inline]
+ fn call(&self, req: Request) -> Self::Future {
+ (**self).call(req)
+ }
+}