Merge pull request #876 from leodasvacas/conn-refactor

Dedup code in connection state update.
This commit is contained in:
Sean McArthur
2016-07-27 16:49:44 -07:00
committed by GitHub

View File

@@ -669,206 +669,195 @@ impl<H: MessageHandler<T>, T: Transport> fmt::Debug for State<H, T> {
} }
impl<H: MessageHandler<T>, T: Transport> State<H, T> { impl<H: MessageHandler<T>, T: Transport> State<H, T> {
fn update<F, K>(&mut self, next: Next, factory: &F) where F: MessageHandlerFactory<K, T>, K: Key { fn update<F, K>(&mut self, next: Next, factory: &F)
let timeout = next.timeout; where F: MessageHandlerFactory<K, T>,
let state = mem::replace(self, State::Closed); K: Key
let new_state = match (state, next.interest) { {
(_, Next_::Remove) => State::Closed, let timeout = next.timeout;
(State::Closed, _) => State::Closed, let state = mem::replace(self, State::Closed);
(State::Init { timeout, .. }, e) => State::Init { match (state, next.interest) {
interest: e, (_, Next_::Remove) |
timeout: timeout, (State::Closed, _) => return, // Keep State::Closed.
}, (State::Init { .. }, e) => {
(State::Http1(http1), Next_::End) => { mem::replace(self,
let reading = match http1.reading { State::Init {
Reading::Body(ref decoder) | interest: e,
Reading::Wait(ref decoder) if decoder.is_eof() => { timeout: timeout,
if http1.keep_alive { });
Reading::KeepAlive
} else {
Reading::Closed
}
},
Reading::KeepAlive => http1.reading,
_ => Reading::Closed,
};
let writing = match http1.writing {
Writing::Wait(encoder) |
Writing::Ready(encoder) => {
if encoder.is_eof() {
if http1.keep_alive {
Writing::KeepAlive
} else {
Writing::Closed
}
} else if let Some(buf) = encoder.finish() {
Writing::Chunk(Chunk {
buf: buf.bytes,
pos: buf.pos,
next: (h1::Encoder::length(0), Next::end())
})
} else {
Writing::Closed
}
}
Writing::Chunk(mut chunk) => {
if chunk.is_written() {
let encoder = chunk.next.0;
//TODO: de-dupe this code and from Writing::Ready
if encoder.is_eof() {
if http1.keep_alive {
Writing::KeepAlive
} else {
Writing::Closed
}
} else if let Some(buf) = encoder.finish() {
Writing::Chunk(Chunk {
buf: buf.bytes,
pos: buf.pos,
next: (h1::Encoder::length(0), Next::end())
})
} else {
Writing::Closed
}
} else {
chunk.next.1 = next;
Writing::Chunk(chunk)
}
},
_ => Writing::Closed,
};
match (reading, writing) {
(Reading::KeepAlive, Writing::KeepAlive) => {
let next = factory.keep_alive_interest();
State::Init {
interest: next.interest,
timeout: next.timeout,
}
},
(reading, Writing::Chunk(chunk)) => {
State::Http1(Http1 {
reading: reading,
writing: Writing::Chunk(chunk),
.. http1
})
}
_ => State::Closed
} }
}, (State::Http1(mut http1), next_) => {
(State::Http1(mut http1), Next_::Read) => { match next_ {
http1.reading = match http1.reading { Next_::Remove => unreachable!(), // Covered in (_, Next_::Remove) case above.
Reading::Init => Reading::Parse, Next_::End => {
Reading::Wait(decoder) => Reading::Body(decoder), let reading = match http1.reading {
same => same Reading::Body(ref decoder) |
}; Reading::Wait(ref decoder) if decoder.is_eof() => {
if http1.keep_alive {
Reading::KeepAlive
} else {
Reading::Closed
}
}
Reading::KeepAlive => http1.reading,
_ => Reading::Closed,
};
let mut writing = Writing::Closed;
let encoder = match http1.writing {
Writing::Wait(enc) |
Writing::Ready(enc) => Some(enc),
Writing::Chunk(mut chunk) => {
if chunk.is_written() {
Some(chunk.next.0)
} else {
chunk.next.1 = next;
writing = Writing::Chunk(chunk);
None
}
}
_ => return, // Keep State::Closed.
};
if let Some(encoder) = encoder {
if encoder.is_eof() {
if http1.keep_alive {
writing = Writing::KeepAlive
}
} else if let Some(buf) = encoder.finish() {
writing = Writing::Chunk(Chunk {
buf: buf.bytes,
pos: buf.pos,
next: (h1::Encoder::length(0), Next::end()),
})
}
};
http1.writing = match http1.writing { match (reading, writing) {
Writing::Ready(encoder) => { (Reading::KeepAlive, Writing::KeepAlive) => {
if encoder.is_eof() { let next = factory.keep_alive_interest();
if http1.keep_alive { mem::replace(self,
Writing::KeepAlive State::Init {
} else { interest: next.interest,
Writing::Closed timeout: next.timeout,
});
return;
}
(reading, Writing::Chunk(chunk)) => {
http1.reading = reading;
http1.writing = Writing::Chunk(chunk);
}
_ => return, // Keep State::Closed.
} }
} else if encoder.is_closed() {
if let Some(buf) = encoder.finish() {
Writing::Chunk(Chunk {
buf: buf.bytes,
pos: buf.pos,
next: (h1::Encoder::length(0), Next::wait())
})
} else {
Writing::Closed
}
} else {
Writing::Wait(encoder)
} }
}, Next_::Read => {
Writing::Chunk(chunk) => if chunk.is_written() { http1.reading = match http1.reading {
Writing::Wait(chunk.next.0) Reading::Init => Reading::Parse,
} else { Reading::Wait(decoder) => Reading::Body(decoder),
Writing::Chunk(chunk) same => same,
}, };
same => same
};
State::Http1(http1) http1.writing = match http1.writing {
}, Writing::Ready(encoder) => {
(State::Http1(mut http1), Next_::Write) => { if encoder.is_eof() {
http1.writing = match http1.writing { if http1.keep_alive {
Writing::Wait(encoder) => Writing::Ready(encoder), Writing::KeepAlive
Writing::Init => Writing::Head, } else {
Writing::Chunk(chunk) => if chunk.is_written() { Writing::Closed
Writing::Ready(chunk.next.0) }
} else { } else if encoder.is_closed() {
Writing::Chunk(chunk) if let Some(buf) = encoder.finish() {
}, Writing::Chunk(Chunk {
same => same buf: buf.bytes,
}; pos: buf.pos,
next: (h1::Encoder::length(0), Next::wait()),
http1.reading = match http1.reading { })
Reading::Body(decoder) => if decoder.is_eof() { } else {
if http1.keep_alive { Writing::Closed
Reading::KeepAlive }
} else { } else {
Reading::Closed Writing::Wait(encoder)
}
}
Writing::Chunk(chunk) => {
if chunk.is_written() {
Writing::Wait(chunk.next.0)
} else {
Writing::Chunk(chunk)
}
}
same => same,
};
} }
} else { Next_::Write => {
Reading::Wait(decoder) http1.writing = match http1.writing {
}, Writing::Wait(encoder) => Writing::Ready(encoder),
same => same Writing::Init => Writing::Head,
}; Writing::Chunk(chunk) => {
State::Http1(http1) if chunk.is_written() {
}, Writing::Ready(chunk.next.0)
(State::Http1(mut http1), Next_::ReadWrite) => { } else {
http1.reading = match http1.reading { Writing::Chunk(chunk)
Reading::Init => Reading::Parse, }
Reading::Wait(decoder) => Reading::Body(decoder), }
same => same same => same,
}; };
http1.writing = match http1.writing {
Writing::Wait(encoder) => Writing::Ready(encoder),
Writing::Init => Writing::Head,
Writing::Chunk(chunk) => if chunk.is_written() {
Writing::Ready(chunk.next.0)
} else {
Writing::Chunk(chunk)
},
same => same
};
State::Http1(http1)
},
(State::Http1(mut http1), Next_::Wait) => {
http1.reading = match http1.reading {
Reading::Body(decoder) => Reading::Wait(decoder),
same => same
};
http1.writing = match http1.writing { http1.reading = match http1.reading {
Writing::Ready(encoder) => Writing::Wait(encoder), Reading::Body(decoder) => {
Writing::Chunk(chunk) => if chunk.is_written() { if decoder.is_eof() {
Writing::Wait(chunk.next.0) if http1.keep_alive {
} else { Reading::KeepAlive
Writing::Chunk(chunk) } else {
}, Reading::Closed
same => same }
}; } else {
State::Http1(http1) Reading::Wait(decoder)
} }
}; }
let new_state = match new_state { same => same,
State::Init { interest, .. } => State::Init { };
timeout: timeout, }
interest: interest, Next_::ReadWrite => {
}, http1.reading = match http1.reading {
State::Http1(mut http1) => { Reading::Init => Reading::Parse,
http1.timeout = timeout; Reading::Wait(decoder) => Reading::Body(decoder),
State::Http1(http1) same => same,
} };
other => other http1.writing = match http1.writing {
}; Writing::Wait(encoder) => Writing::Ready(encoder),
mem::replace(self, new_state); Writing::Init => Writing::Head,
} Writing::Chunk(chunk) => {
if chunk.is_written() {
Writing::Ready(chunk.next.0)
} else {
Writing::Chunk(chunk)
}
}
same => same,
};
}
Next_::Wait => {
http1.reading = match http1.reading {
Reading::Body(decoder) => Reading::Wait(decoder),
same => same,
};
http1.writing = match http1.writing {
Writing::Ready(encoder) => Writing::Wait(encoder),
Writing::Chunk(chunk) => {
if chunk.is_written() {
Writing::Wait(chunk.next.0)
} else {
Writing::Chunk(chunk)
}
}
same => same,
};
}
}
http1.timeout = timeout;
mem::replace(self, State::Http1(http1));
}
};
}
} }
// These Reading and Writing stuff should probably get moved into h1/message.rs // These Reading and Writing stuff should probably get moved into h1/message.rs