1 use std::convert::Infallible; 2 use std::task::{Context, Poll}; 3 use tower_service::Service; 4 5 /// A [`MakeService`] that produces services by cloning an inner service. 6 /// 7 /// [`MakeService`]: super::MakeService 8 /// 9 /// # Example 10 /// 11 /// ``` 12 /// # use std::task::{Context, Poll}; 13 /// # use std::pin::Pin; 14 /// # use std::convert::Infallible; 15 /// use tower::make::{MakeService, Shared}; 16 /// use tower::buffer::Buffer; 17 /// use tower::Service; 18 /// use futures::future::{Ready, ready}; 19 /// 20 /// // An example connection type 21 /// struct Connection {} 22 /// 23 /// // An example request type 24 /// struct Request {} 25 /// 26 /// // An example response type 27 /// struct Response {} 28 /// 29 /// // Some service that doesn't implement `Clone` 30 /// struct MyService; 31 /// 32 /// impl Service<Request> for MyService { 33 /// type Response = Response; 34 /// type Error = Infallible; 35 /// type Future = Ready<Result<Response, Infallible>>; 36 /// 37 /// fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { 38 /// Poll::Ready(Ok(())) 39 /// } 40 /// 41 /// fn call(&mut self, req: Request) -> Self::Future { 42 /// ready(Ok(Response {})) 43 /// } 44 /// } 45 /// 46 /// // Example function that runs a service by accepting new connections and using 47 /// // `Make` to create new services that might be bound to the connection. 48 /// // 49 /// // This is similar to what you might find in hyper. 50 /// async fn serve_make_service<Make>(make: Make) 51 /// where 52 /// Make: MakeService<Connection, Request> 53 /// { 54 /// // ... 55 /// } 56 /// 57 /// # async { 58 /// // Our service 59 /// let svc = MyService; 60 /// 61 /// // Make it `Clone` by putting a channel in front 62 /// let buffered = Buffer::new(svc, 1024); 63 /// 64 /// // Convert it into a `MakeService` 65 /// let make = Shared::new(buffered); 66 /// 67 /// // Run the service and just ignore the `Connection`s as `MyService` doesn't need them 68 /// serve_make_service(make).await; 69 /// # }; 70 /// ``` 71 #[derive(Debug, Clone, Copy)] 72 pub struct Shared<S> { 73 service: S, 74 } 75 76 impl<S> Shared<S> { 77 /// Create a new [`Shared`] from a service. new(service: S) -> Self78 pub fn new(service: S) -> Self { 79 Self { service } 80 } 81 } 82 83 impl<S, T> Service<T> for Shared<S> 84 where 85 S: Clone, 86 { 87 type Response = S; 88 type Error = Infallible; 89 type Future = SharedFuture<S>; 90 poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>91 fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { 92 Poll::Ready(Ok(())) 93 } 94 call(&mut self, _target: T) -> Self::Future95 fn call(&mut self, _target: T) -> Self::Future { 96 SharedFuture::new(futures_util::future::ready(Ok(self.service.clone()))) 97 } 98 } 99 100 opaque_future! { 101 /// Response future from [`Shared`] services. 102 pub type SharedFuture<S> = futures_util::future::Ready<Result<S, Infallible>>; 103 } 104 105 #[cfg(test)] 106 mod tests { 107 use super::*; 108 use crate::make::MakeService; 109 use crate::service_fn; 110 use futures::future::poll_fn; 111 echo<R>(req: R) -> Result<R, Infallible>112 async fn echo<R>(req: R) -> Result<R, Infallible> { 113 Ok(req) 114 } 115 116 #[tokio::test] as_make_service()117 async fn as_make_service() { 118 let mut shared = Shared::new(service_fn(echo::<&'static str>)); 119 120 poll_fn(|cx| MakeService::<(), _>::poll_ready(&mut shared, cx)) 121 .await 122 .unwrap(); 123 let mut svc = shared.make_service(()).await.unwrap(); 124 125 poll_fn(|cx| svc.poll_ready(cx)).await.unwrap(); 126 let res = svc.call("foo").await.unwrap(); 127 128 assert_eq!(res, "foo"); 129 } 130 131 #[tokio::test] as_make_service_into_service()132 async fn as_make_service_into_service() { 133 let shared = Shared::new(service_fn(echo::<&'static str>)); 134 let mut shared = MakeService::<(), _>::into_service(shared); 135 136 poll_fn(|cx| Service::<()>::poll_ready(&mut shared, cx)) 137 .await 138 .unwrap(); 139 let mut svc = shared.call(()).await.unwrap(); 140 141 poll_fn(|cx| svc.poll_ready(cx)).await.unwrap(); 142 let res = svc.call("foo").await.unwrap(); 143 144 assert_eq!(res, "foo"); 145 } 146 } 147