feat(service): use tower_service::Service for hyper::service
This commit is contained in:
		
				
					committed by
					
						 Sean McArthur
						Sean McArthur
					
				
			
			
				
	
			
			
			
						parent
						
							53a437c382
						
					
				
				
					commit
					ec520d5602
				
			| @@ -6,10 +6,7 @@ use crate::common::{Future, Poll, task}; | ||||
| use super::Service; | ||||
|  | ||||
| /// An asynchronous constructor of `Service`s. | ||||
| pub trait MakeService<Target> { | ||||
|     /// The `Payload` body of the `http::Request`. | ||||
|     type ReqBody: Payload; | ||||
|  | ||||
| pub trait MakeService<Target, ReqBody>: sealed::Sealed<Target, ReqBody> { | ||||
|     /// The `Payload` body of the `http::Response`. | ||||
|     type ResBody: Payload; | ||||
|  | ||||
| @@ -18,7 +15,7 @@ pub trait MakeService<Target> { | ||||
|  | ||||
|     /// The resolved `Service` from `new_service()`. | ||||
|     type Service: Service< | ||||
|         ReqBody=Self::ReqBody, | ||||
|         ReqBody, | ||||
|         ResBody=Self::ResBody, | ||||
|         Error=Self::Error, | ||||
|     >; | ||||
| @@ -42,15 +39,46 @@ pub trait MakeService<Target> { | ||||
|     fn make_service(&mut self, target: Target) -> Self::Future; | ||||
| } | ||||
|  | ||||
| impl<T, Target, S, B1, B2, E, F> MakeService<Target, B1> for T  | ||||
| where  | ||||
|     T: for<'a> tower_service::Service<&'a Target, Response = S, Error = E, Future = F>, | ||||
|     S: tower_service::Service<crate::Request<B1>, Response = crate::Response<B2>>, | ||||
|     E: Into<Box<dyn std::error::Error + Send + Sync>>, | ||||
|     S::Error: Into<Box<dyn std::error::Error + Send + Sync>>, | ||||
|     B1: Payload, | ||||
|     B2: Payload, | ||||
|     F: Future<Output = Result<S, E>>, | ||||
| { | ||||
|     type ResBody = B2; | ||||
|     type Error = S::Error; | ||||
|     type Service = S; | ||||
|     type Future = F; | ||||
|     type MakeError = E; | ||||
|  | ||||
|     fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::MakeError>> { | ||||
|          tower_service::Service::poll_ready(self, cx) | ||||
|     } | ||||
|  | ||||
|     fn make_service(&mut self, req: Target) -> Self::Future { | ||||
|         tower_service::Service::call(self, &req) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<T, Target, S, B1, B2> sealed::Sealed<Target, B1> for T  | ||||
| where  | ||||
|     T: for<'a> tower_service::Service<&'a Target, Response = S>, | ||||
|     S: tower_service::Service<crate::Request<B1>, Response = crate::Response<B2>> | ||||
| { | ||||
| } | ||||
|  | ||||
| // Just a sort-of "trait alias" of `MakeService`, not to be implemented | ||||
| // by anyone, only used as bounds. | ||||
| #[doc(hidden)] | ||||
| pub trait MakeServiceRef<Target>: self::sealed::Sealed<Target> { | ||||
|     type ReqBody: Payload; | ||||
| pub trait MakeServiceRef<Target, ReqBody>: self::sealed::Sealed<Target, ReqBody> { | ||||
|     type ResBody: Payload; | ||||
|     type Error: Into<Box<dyn StdError + Send + Sync>>; | ||||
|     type Service: Service< | ||||
|         ReqBody=Self::ReqBody, | ||||
|         ReqBody, | ||||
|         ResBody=Self::ResBody, | ||||
|         Error=Self::Error, | ||||
|     >; | ||||
| @@ -73,19 +101,18 @@ pub trait MakeServiceRef<Target>: self::sealed::Sealed<Target> { | ||||
|     fn make_service_ref(&mut self, target: &Target) -> Self::Future; | ||||
| } | ||||
|  | ||||
| impl<T, Target, E, ME, S, F, IB, OB> MakeServiceRef<Target> for T | ||||
| impl<T, Target, E, ME, S, F, IB, OB> MakeServiceRef<Target, IB> for T | ||||
| where | ||||
|     T: for<'a> MakeService<&'a Target, Error=E, MakeError=ME, Service=S, Future=F, ReqBody=IB, ResBody=OB>, | ||||
|     T: for<'a> tower_service::Service<&'a Target, Error=ME, Response=S, Future=F>, | ||||
|     E: Into<Box<dyn StdError + Send + Sync>>, | ||||
|     ME: Into<Box<dyn StdError + Send + Sync>>, | ||||
|     S: Service<ReqBody=IB, ResBody=OB, Error=E>, | ||||
|     S: tower_service::Service<crate::Request<IB>, Response=crate::Response<OB>, Error=E>, | ||||
|     F: Future<Output=Result<S, ME>>, | ||||
|     IB: Payload, | ||||
|     OB: Payload, | ||||
| { | ||||
|     type Error = E; | ||||
|     type Service = S; | ||||
|     type ReqBody = IB; | ||||
|     type ResBody = OB; | ||||
|     type MakeError = ME; | ||||
|     type Future = F; | ||||
| @@ -97,22 +124,10 @@ where | ||||
|     } | ||||
|  | ||||
|     fn make_service_ref(&mut self, target: &Target) -> Self::Future { | ||||
|         self.make_service(target) | ||||
|         self.call(target) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<T, Target, E, ME, S, F, IB, OB> self::sealed::Sealed<Target> for T | ||||
| where | ||||
|     T: for<'a> MakeService<&'a Target, Error=E, MakeError=ME, Service=S, Future=F, ReqBody=IB, ResBody=OB>, | ||||
|     E: Into<Box<dyn StdError + Send + Sync>>, | ||||
|     ME: Into<Box<dyn StdError + Send + Sync>>, | ||||
|     S: Service<ReqBody=IB, ResBody=OB, Error=E>, | ||||
|     F: Future<Output=Result<S, ME>>, | ||||
|     IB: Payload, | ||||
|     OB: Payload, | ||||
| {} | ||||
|  | ||||
|  | ||||
| /// Create a `MakeService` from a function. | ||||
| /// | ||||
| /// # Example | ||||
| @@ -167,23 +182,21 @@ pub struct MakeServiceFn<F> { | ||||
|     f: F, | ||||
| } | ||||
|  | ||||
| impl<'t, F, Target, Ret, ReqBody, ResBody, Svc, MkErr> MakeService<&'t Target> for MakeServiceFn<F> | ||||
| impl<'t, F, Ret, Target, Svc, MkErr> tower_service::Service<&'t Target> for MakeServiceFn<F> | ||||
| where | ||||
|     F: FnMut(&Target) -> Ret, | ||||
|     Ret: Future<Output=Result<Svc, MkErr>>, | ||||
|     Svc: Service<ReqBody=ReqBody, ResBody=ResBody>, | ||||
|     MkErr: Into<Box<dyn StdError + Send + Sync>>, | ||||
|     ReqBody: Payload, | ||||
|     ResBody: Payload, | ||||
| { | ||||
|     type ReqBody = ReqBody; | ||||
|     type ResBody = ResBody; | ||||
|     type Error = Svc::Error; | ||||
|     type Service = Svc; | ||||
|     type Error = MkErr; | ||||
|     type Response = Svc; | ||||
|     type Future = Ret; | ||||
|     type MakeError = MkErr; | ||||
|  | ||||
|     fn make_service(&mut self, target: &'t Target) -> Self::Future { | ||||
|     fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> { | ||||
|         Poll::Ready(Ok(())) | ||||
|     } | ||||
|  | ||||
|     fn call(&mut self, target: &'t Target) -> Self::Future { | ||||
|         (self.f)(target) | ||||
|     } | ||||
| } | ||||
| @@ -196,7 +209,7 @@ impl<F> fmt::Debug for MakeServiceFn<F> { | ||||
| } | ||||
|  | ||||
| mod sealed { | ||||
|     pub trait Sealed<T> {} | ||||
|     pub trait Sealed<T, B> {} | ||||
|  | ||||
|     pub trait CantImpl {} | ||||
|  | ||||
|   | ||||
| @@ -7,10 +7,7 @@ use crate::common::{Future, Never, Poll, task}; | ||||
| use crate::{Request, Response}; | ||||
|  | ||||
| /// An asynchronous function from `Request` to `Response`. | ||||
| pub trait Service { | ||||
|     /// The `Payload` body of the `http::Request`. | ||||
|     type ReqBody: Payload; | ||||
|  | ||||
| pub trait Service<ReqBody>: sealed::Sealed<ReqBody> { | ||||
|     /// The `Payload` body of the `http::Response`. | ||||
|     type ResBody: Payload; | ||||
|  | ||||
| @@ -34,7 +31,37 @@ pub trait Service { | ||||
|     } | ||||
|  | ||||
|     /// Calls this `Service` with a request, returning a `Future` of the response. | ||||
|     fn call(&mut self, req: Request<Self::ReqBody>) -> Self::Future; | ||||
|     fn call(&mut self, req: Request<ReqBody>) -> Self::Future; | ||||
| } | ||||
|  | ||||
| impl<T, B1, B2> Service<B1> for T  | ||||
| where  | ||||
|     T: tower_service::Service<Request<B1>, Response = Response<B2>>, | ||||
|     B2: Payload, | ||||
|     T::Error: Into<Box<dyn StdError + Send + Sync>>, | ||||
| { | ||||
|     type ResBody = B2; | ||||
|  | ||||
|     type Error = T::Error; | ||||
|     type Future = T::Future; | ||||
|  | ||||
|     fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> { | ||||
|         tower_service::Service::poll_ready(self, cx) | ||||
|     } | ||||
|  | ||||
|     fn call(&mut self, req: Request<B1>) -> Self::Future { | ||||
|         tower_service::Service::call(self, req) | ||||
|     } | ||||
| } | ||||
|  | ||||
| impl<T, B1, B2> sealed::Sealed<B1> for T  | ||||
| where  | ||||
|     T: tower_service::Service<Request<B1>, Response = Response<B2>>, | ||||
|     B2: Payload, | ||||
| {} | ||||
|  | ||||
| mod sealed { | ||||
|     pub trait Sealed<T> {} | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -74,7 +101,7 @@ pub struct ServiceFn<F, R> { | ||||
|     _req: PhantomData<fn(R)>, | ||||
| } | ||||
|  | ||||
| impl<F, ReqBody, Ret, ResBody, E> Service for ServiceFn<F, ReqBody> | ||||
| impl<F, ReqBody, Ret, ResBody, E> tower_service::Service<crate::Request<ReqBody>> for ServiceFn<F, ReqBody> | ||||
| where | ||||
|     F: FnMut(Request<ReqBody>) -> Ret, | ||||
|     ReqBody: Payload, | ||||
| @@ -82,12 +109,15 @@ where | ||||
|     E: Into<Box<dyn StdError + Send + Sync>>, | ||||
|     ResBody: Payload, | ||||
| { | ||||
|     type ReqBody = ReqBody; | ||||
|     type ResBody = ResBody; | ||||
|     type Response = crate::Response<ResBody>; | ||||
|     type Error = E; | ||||
|     type Future = Ret; | ||||
|  | ||||
|     fn call(&mut self, req: Request<Self::ReqBody>) -> Self::Future { | ||||
|     fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> { | ||||
|         Poll::Ready(Ok(())) | ||||
|     } | ||||
|  | ||||
|     fn call(&mut self, req: Request<ReqBody>) -> Self::Future { | ||||
|         (self.f)(req) | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user