Make the TcpServer work with bytes instead of strings

This makes it possible to implement byte-based protocols using TcpServer, instead of only being able to implement string-based protocols.
This commit is contained in:
Ben Bridle 2021-08-07 14:20:59 +12:00
parent 3f46685100
commit ccd4da433b
3 changed files with 8 additions and 15 deletions

View File

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

View File

@ -1,13 +1,13 @@
pub trait Request {
type Response;
fn from_string(request_string: &str) -> RequestParseResult<Self, Self::Response>
fn from_bytes(request_bytes: &[u8]) -> RequestParseResult<Self, Self::Response>
where
Self: Sized,
Self::Response: Response;
}
pub trait Response {
fn to_string(self) -> String;
fn to_bytes(self) -> Vec<u8>;
}
pub type ProcessRequest<Req, Res> = fn(request: &Req) -> Res;

View File

@ -144,19 +144,13 @@ impl<
self.remove_connection(event.token()).unwrap();
return;
}
Ok(_) => match std::str::from_utf8(&buffer) {
Ok(s) => request_data.push_str(s.trim_matches(char::from(0))),
Err(e) => panic!(
"Incoming data from {:?} is not valid UTF-8: {}",
connection.address, e
),
},
Ok(len) => request_data.extend_from_slice(&buffer[..len]),
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
Err(e) => panic!("Unexpected error: {}", e),
};
}
match Req::from_string(&request_data) {
match Req::from_bytes(&request_data) {
RequestParseResult::Complete(request) => {
let mut connection =
std::mem::replace(&mut self.connections[token.0], None).unwrap();
@ -180,9 +174,8 @@ impl<
let token = event.token();
let mut connection = std::mem::replace(&mut self.connections[token.0], None).unwrap();
if let RequestState::Outgoing(response) = connection.state {
let response_string = response.to_string();
let bytes = response_string.as_bytes();
connection.stream.write_all(bytes).unwrap();
let bytes = response.to_bytes();
connection.stream.write_all(&bytes).unwrap();
} else {
info!("Received write event for non-outgoing connection")
}