Give control of the partial request bytes to Request

Before, the partially constructed byte sequence for the request was held outside of the Request object, and each time the program tried to create a Request out of the byte sequence the entire sequence would need to be re-parsed. Now, a Request is constructed up-front, and bytes are periodically pushed to it. This enables the library user to parse more efficiently, by keeping partial parse results inside the Request object and only parsing bytes when they're new to the Request.
This commit is contained in:
Ben Bridle 2021-08-07 15:05:48 +12:00
parent ccd4da433b
commit 1e83969ebd
3 changed files with 9 additions and 6 deletions

View File

@ -15,13 +15,13 @@ impl<Req: Request, Res: Response> Connection<Req, Res> {
stream,
address,
token,
state: RequestState::Incoming(Vec::new()),
state: RequestState::Incoming(Req::new()),
}
}
}
pub enum RequestState<Req: Request, Res: Response> {
Incoming(Vec<u8>),
Incoming(Req),
Processing(Req),
Outgoing(Res),
}

View File

@ -1,6 +1,9 @@
pub trait Request {
type Response;
fn from_bytes(request_bytes: &[u8]) -> RequestParseResult<Self, Self::Response>
fn new() -> Self;
fn push_bytes(&mut self, bytes: &[u8]);
fn parse(&mut self) -> RequestParseResult<Self, Self::Response>
where
Self: Sized,
Self::Response: Response;

View File

@ -136,7 +136,7 @@ impl<
fn process_read_event(&mut self, event: &Event) {
let token = event.token();
let connection = self.connections[token.0].as_mut().unwrap();
if let RequestState::Incoming(ref mut request_data) = connection.state {
if let RequestState::Incoming(ref mut req) = connection.state {
loop {
let mut buffer = [0 as u8; 1024];
match connection.stream.read(&mut buffer) {
@ -144,13 +144,13 @@ impl<
self.remove_connection(event.token()).unwrap();
return;
}
Ok(len) => request_data.extend_from_slice(&buffer[..len]),
Ok(len) => req.push_bytes(&buffer[..len]),
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
Err(e) => panic!("Unexpected error: {}", e),
};
}
match Req::from_bytes(&request_data) {
match req.parse() {
RequestParseResult::Complete(request) => {
let mut connection =
std::mem::replace(&mut self.connections[token.0], None).unwrap();