layer.rs 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. use std::pin::Pin;
  2. use tracing_futures::Instrument;
  3. use http::{Request, Response};
  4. /// A layer that wraps a service. This can be used to add additional information to the request, or response on top of some other service
  5. pub trait Layer: Send + Sync + 'static {
  6. /// Wrap a boxed service with this layer
  7. fn layer(&self, inner: BoxedService) -> BoxedService;
  8. }
  9. impl<L> Layer for L
  10. where
  11. L: tower_layer::Layer<BoxedService> + Sync + Send + 'static,
  12. L::Service: Service + Send + 'static,
  13. {
  14. fn layer(&self, inner: BoxedService) -> BoxedService {
  15. BoxedService(Box::new(self.layer(inner)))
  16. }
  17. }
  18. /// A service is a function that takes a request and returns an async response
  19. pub trait Service {
  20. /// Run the service and produce a future that resolves to a response
  21. fn run(
  22. &mut self,
  23. req: http::Request<hyper::body::Body>,
  24. ) -> Pin<
  25. Box<
  26. dyn std::future::Future<
  27. Output = Result<Response<hyper::body::Body>, server_fn::ServerFnError>,
  28. > + Send,
  29. >,
  30. >;
  31. }
  32. impl<S> Service for S
  33. where
  34. S: tower::Service<http::Request<hyper::body::Body>, Response = Response<hyper::body::Body>>,
  35. S::Future: Send + 'static,
  36. S::Error: Into<server_fn::ServerFnError>,
  37. {
  38. fn run(
  39. &mut self,
  40. req: http::Request<hyper::body::Body>,
  41. ) -> Pin<
  42. Box<
  43. dyn std::future::Future<
  44. Output = Result<Response<hyper::body::Body>, server_fn::ServerFnError>,
  45. > + Send,
  46. >,
  47. > {
  48. let fut = self.call(req).instrument(tracing::trace_span!(
  49. "service",
  50. "{}",
  51. std::any::type_name::<S>()
  52. ));
  53. Box::pin(async move { fut.await.map_err(|err| err.into()) })
  54. }
  55. }
  56. /// A boxed service is a type-erased service that can be used without knowing the underlying type
  57. pub struct BoxedService(pub Box<dyn Service + Send>);
  58. impl tower::Service<http::Request<hyper::body::Body>> for BoxedService {
  59. type Response = http::Response<hyper::body::Body>;
  60. type Error = server_fn::ServerFnError;
  61. type Future = Pin<
  62. Box<
  63. dyn std::future::Future<
  64. Output = Result<http::Response<hyper::body::Body>, server_fn::ServerFnError>,
  65. > + Send,
  66. >,
  67. >;
  68. fn poll_ready(
  69. &mut self,
  70. _cx: &mut std::task::Context<'_>,
  71. ) -> std::task::Poll<Result<(), Self::Error>> {
  72. Ok(()).into()
  73. }
  74. fn call(&mut self, req: Request<hyper::body::Body>) -> Self::Future {
  75. self.0.run(req)
  76. }
  77. }