Skip to content
This repository was archived by the owner on Apr 16, 2020. It is now read-only.
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 18 additions & 48 deletions src/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ where T: AsyncRead + AsyncWrite,
/// The service has closed, so poll until connection is closed.
GoAway {
connection: Accept<T, SendBuf<B::Item>>,
error: Error<S>,
error: Error<S::Error, S::MakeError>,
},

/// Everything is closed up.
Expand Down Expand Up @@ -93,20 +93,19 @@ where B: Body,
}

/// Error produced by a `Connection`.
pub enum Error<S>
where S: MakeService<(), Request<RecvBody>>,
{
#[derive(Debug)]
pub enum Error<E, ME = E> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since Server accepts a MakeService is there ever a chance that this won't be S::Error or S::MakeError?

Copy link
Contributor Author

@mzabaluev mzabaluev Jan 18, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since Server accepts a MakeService is there ever a chance that this won't be S::Error or S::MakeError?

No, and it's a good thing: Error does not need to drag the full MakeService implementation type into its signature, because it only needs two subdomain error types which are: 1) usually much simpler; 2) are types of actual contents of the Error enum, which makes Debug and other impls auto-derivable as seen in the commit.

Every meaningful declaration using this Error type locks its type parameters into the associated types of MakeService. Code that attempts to misuse the type parameters, e.g. by unintentionally swapping them, would either fail type-checking at use of the constructors Error::NewService and Error::Service, or would look obviously wrong.

/// Error produced during the HTTP/2.0 handshake.
Handshake(h2::Error),

/// Error produced by the HTTP/2.0 stream
Protocol(h2::Error),

/// Error produced when obtaining the service
NewService(S::MakeError),
NewService(ME),

/// Error produced by the service
Service(S::Error),
Service(E),

/// Error produced when attempting to spawn a task
Execute,
Expand Down Expand Up @@ -205,7 +204,7 @@ where T: AsyncRead + AsyncWrite,
F: Modify,
{
type Item = ();
type Error = Error<S>;
type Error = Error<S::Error, S::MakeError>;

fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
// Code is in poll2 to make sure any Err returned
Expand Down Expand Up @@ -245,7 +244,7 @@ where T: AsyncRead + AsyncWrite,
self.state = State::Done;
}

fn poll2(&mut self) -> Poll<(), Error<S>> {
fn poll2(&mut self) -> Poll<(), Error<S::Error, S::MakeError>> {
loop {
match self.state {
State::Init(..) => try_ready!(self.poll_init()),
Expand All @@ -264,7 +263,7 @@ where T: AsyncRead + AsyncWrite,
}
}

fn poll_init(&mut self) -> Poll<(), Error<S>> {
fn poll_init(&mut self) -> Poll<(), Error<S::Error, S::MakeError>> {
use self::State::*;

let (connection, service) = match self.state {
Expand All @@ -277,7 +276,7 @@ where T: AsyncRead + AsyncWrite,
Ok(().into())
}

fn poll_main(&mut self) -> Poll<PollMain, Error<S>> {
fn poll_main(&mut self) -> Poll<PollMain, Error<S::Error, S::MakeError>> {
let error = match self.state {
State::Ready { ref mut connection, ref mut service } => loop {
// Make sure the service is ready
Expand Down Expand Up @@ -351,7 +350,7 @@ where T: AsyncRead + AsyncWrite,
}
}

fn poll_goaway(&mut self) -> Poll<(), Error<S>> {
fn poll_goaway(&mut self) -> Poll<(), Error<S::Error, S::MakeError>> {
match self.state {
State::GoAway { ref mut connection, .. } => {
try_ready!(connection.poll_close().map_err(Error::Protocol));
Expand Down Expand Up @@ -479,47 +478,19 @@ where T: Future<Item = Response<B>>,

// ===== impl Error =====

impl<S> Error<S>
where S: MakeService<(), Request<RecvBody>>,
{
fn from_init(err: Either<h2::Error, S::MakeError>) -> Self {
impl<E, ME> Error<E, ME> {
fn from_init(err: Either<h2::Error, ME>) -> Self {
match err {
Either::A(err) => Error::Handshake(err),
Either::B(err) => Error::NewService(err),
}
}
}

impl<S> fmt::Debug for Error<S>
where
S: MakeService<(), Request<RecvBody>>,
S::MakeError: fmt::Debug,
S::Error: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::Handshake(ref why) => f.debug_tuple("Handshake")
.field(why)
.finish(),
Error::Protocol(ref why) => f.debug_tuple("Protocol")
.field(why)
.finish(),
Error::NewService(ref why) => f.debug_tuple("NewService")
.field(why)
.finish(),
Error::Service(ref why) => f.debug_tuple("Service")
.field(why)
.finish(),
Error::Execute => f.debug_tuple("Execute").finish(),
}
}
}

impl<S> fmt::Display for Error<S>
impl<E, ME> fmt::Display for Error<E, ME>
where
S: MakeService<(), Request<RecvBody>>,
S::MakeError: fmt::Display,
S::Error: fmt::Display,
E: fmt::Display,
ME: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Expand All @@ -537,11 +508,10 @@ where
}
}

impl<S> error::Error for Error<S>
impl<E, ME> error::Error for Error<E, ME>
where
S: MakeService<(), Request<RecvBody>>,
S::MakeError: error::Error,
S::Error: error::Error,
E: error::Error,
ME: error::Error,
{
fn cause(&self) -> Option<&error::Error> {
match *self {
Expand Down