From af8d11b2bf4ebe1f69fc1ad1251ae58afd14d6ca Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 27 Oct 2017 16:04:28 -0700 Subject: [PATCH] chore(server): remove stream generic from new Connection type --- src/server/mod.rs | 77 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 66 insertions(+), 11 deletions(-) diff --git a/src/server/mod.rs b/src/server/mod.rs index 52594a41..b4f06f65 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -173,7 +173,7 @@ impl + 'static> Http { /// driven on the connection. /// /// This additionally skips the tokio-proto infrastructure internally. - pub fn no_proto(&self, io: I, service: S) -> Connection + pub fn no_proto(&self, io: I, service: S) -> Connection where S: Service, Error = ::Error> + 'static, Bd: Stream + 'static, I: AsyncRead + AsyncWrite + 'static, @@ -211,19 +211,73 @@ impl + 'static> Http { } } +use self::hyper_service::HyperService; +mod hyper_service { + use super::{Request, Response, Service, Stream}; + /// A "trait alias" for any type that implements `Service` with hyper's + /// Request, Response, and Error types, and a streaming body. + /// + /// There is an auto implementation inside hyper, so no one can actually + /// implement this trait. It simply exists to reduce the amount of generics + /// needed. + pub trait HyperService: Service + Sealed { + #[doc(hidden)] + type ResponseBody; + #[doc(hidden)] + type Sealed: Sealed2; + } + + pub trait Sealed {} + pub trait Sealed2 {} + + #[allow(missing_debug_implementations)] + pub struct Opaque { + _inner: (), + } + + impl Sealed2 for Opaque {} + + impl Sealed for S + where + S: Service< + Request=Request, + Response=Response, + Error=::Error, + >, + B: Stream, + B::Item: AsRef<[u8]>, + {} + + impl HyperService for S + where + S: Service< + Request=Request, + Response=Response, + Error=::Error, + >, + S: Sealed, + B: Stream, + B::Item: AsRef<[u8]>, + { + type ResponseBody = B; + type Sealed = Opaque; + } + +} /// A future binding a connection with a Service. /// /// Polling this future will drive HTTP forward. #[must_use = "futures do nothing unless polled"] -pub struct Connection -where S: Service, - B: Stream, - B::Item: AsRef<[u8]>, +pub struct Connection +where + S: HyperService, + S::ResponseBody: Stream, + ::Item: AsRef<[u8]>, { - conn: proto::dispatch::Dispatcher, B, I, B::Item, proto::ServerTransaction, proto::KA>, + conn: proto::dispatch::Dispatcher, S::ResponseBody, I, ::Item, proto::ServerTransaction, proto::KA>, } -impl Future for Connection +impl Future for Connection where S: Service, Error = ::Error> + 'static, I: AsyncRead + AsyncWrite + 'static, B: Stream + 'static, @@ -238,10 +292,11 @@ where S: Service, Error = ::Error> + ' } } -impl fmt::Debug for Connection -where S: Service, - B: Stream, - B::Item: AsRef<[u8]>, +impl fmt::Debug for Connection +where + S: HyperService, + S::ResponseBody: Stream, + ::Item: AsRef<[u8]>, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("Connection")