1 #![warn( 2 missing_debug_implementations, 3 missing_docs, 4 rust_2018_idioms, 5 unreachable_pub 6 )] 7 #![forbid(unsafe_code)] 8 // `rustdoc::broken_intra_doc_links` is checked on CI 9 10 //! Layer traits and extensions. 11 //! 12 //! A layer decorates an service and provides additional functionality. It 13 //! allows other services to be composed with the service that implements layer. 14 //! 15 //! A middleware implements the [`Layer`] and [`Service`] trait. 16 //! 17 //! [`Service`]: https://docs.rs/tower/latest/tower/trait.Service.html 18 19 mod identity; 20 mod layer_fn; 21 mod stack; 22 mod tuple; 23 24 pub use self::{ 25 identity::Identity, 26 layer_fn::{layer_fn, LayerFn}, 27 stack::Stack, 28 }; 29 30 /// Decorates a [`Service`], transforming either the request or the response. 31 /// 32 /// Often, many of the pieces needed for writing network applications can be 33 /// reused across multiple services. The `Layer` trait can be used to write 34 /// reusable components that can be applied to very different kinds of services; 35 /// for example, it can be applied to services operating on different protocols, 36 /// and to both the client and server side of a network transaction. 37 /// 38 /// # Log 39 /// 40 /// Take request logging as an example: 41 /// 42 /// ```rust 43 /// # use tower_service::Service; 44 /// # use std::task::{Poll, Context}; 45 /// # use tower_layer::Layer; 46 /// # use std::fmt; 47 /// 48 /// pub struct LogLayer { 49 /// target: &'static str, 50 /// } 51 /// 52 /// impl<S> Layer<S> for LogLayer { 53 /// type Service = LogService<S>; 54 /// 55 /// fn layer(&self, service: S) -> Self::Service { 56 /// LogService { 57 /// target: self.target, 58 /// service 59 /// } 60 /// } 61 /// } 62 /// 63 /// // This service implements the Log behavior 64 /// pub struct LogService<S> { 65 /// target: &'static str, 66 /// service: S, 67 /// } 68 /// 69 /// impl<S, Request> Service<Request> for LogService<S> 70 /// where 71 /// S: Service<Request>, 72 /// Request: fmt::Debug, 73 /// { 74 /// type Response = S::Response; 75 /// type Error = S::Error; 76 /// type Future = S::Future; 77 /// 78 /// fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { 79 /// self.service.poll_ready(cx) 80 /// } 81 /// 82 /// fn call(&mut self, request: Request) -> Self::Future { 83 /// // Insert log statement here or other functionality 84 /// println!("request = {:?}, target = {:?}", request, self.target); 85 /// self.service.call(request) 86 /// } 87 /// } 88 /// ``` 89 /// 90 /// The above log implementation is decoupled from the underlying protocol and 91 /// is also decoupled from client or server concerns. In other words, the same 92 /// log middleware could be used in either a client or a server. 93 /// 94 /// [`Service`]: https://docs.rs/tower/latest/tower/trait.Service.html 95 pub trait Layer<S> { 96 /// The wrapped service 97 type Service; 98 /// Wrap the given service with the middleware, returning a new service 99 /// that has been decorated with the middleware. layer(&self, inner: S) -> Self::Service100 fn layer(&self, inner: S) -> Self::Service; 101 } 102 103 impl<'a, T, S> Layer<S> for &'a T 104 where 105 T: ?Sized + Layer<S>, 106 { 107 type Service = T::Service; 108 layer(&self, inner: S) -> Self::Service109 fn layer(&self, inner: S) -> Self::Service { 110 (**self).layer(inner) 111 } 112 } 113