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:
parent
3f46685100
commit
ccd4da433b
|
@ -15,13 +15,13 @@ impl<Req: Request, Res: Response> Connection<Req, Res> {
|
||||||
stream,
|
stream,
|
||||||
address,
|
address,
|
||||||
token,
|
token,
|
||||||
state: RequestState::Incoming(String::new()),
|
state: RequestState::Incoming(Vec::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum RequestState<Req: Request, Res: Response> {
|
pub enum RequestState<Req: Request, Res: Response> {
|
||||||
Incoming(String),
|
Incoming(Vec<u8>),
|
||||||
Processing(Req),
|
Processing(Req),
|
||||||
Outgoing(Res),
|
Outgoing(Res),
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
pub trait Request {
|
pub trait Request {
|
||||||
type Response;
|
type Response;
|
||||||
fn from_string(request_string: &str) -> RequestParseResult<Self, Self::Response>
|
fn from_bytes(request_bytes: &[u8]) -> RequestParseResult<Self, Self::Response>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
Self::Response: Response;
|
Self::Response: Response;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Response {
|
pub trait Response {
|
||||||
fn to_string(self) -> String;
|
fn to_bytes(self) -> Vec<u8>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type ProcessRequest<Req, Res> = fn(request: &Req) -> Res;
|
pub type ProcessRequest<Req, Res> = fn(request: &Req) -> Res;
|
||||||
|
|
|
@ -144,19 +144,13 @@ impl<
|
||||||
self.remove_connection(event.token()).unwrap();
|
self.remove_connection(event.token()).unwrap();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Ok(_) => match std::str::from_utf8(&buffer) {
|
Ok(len) => request_data.extend_from_slice(&buffer[..len]),
|
||||||
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
|
|
||||||
),
|
|
||||||
},
|
|
||||||
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
|
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
|
||||||
Err(e) => panic!("Unexpected error: {}", e),
|
Err(e) => panic!("Unexpected error: {}", e),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
match Req::from_string(&request_data) {
|
match Req::from_bytes(&request_data) {
|
||||||
RequestParseResult::Complete(request) => {
|
RequestParseResult::Complete(request) => {
|
||||||
let mut connection =
|
let mut connection =
|
||||||
std::mem::replace(&mut self.connections[token.0], None).unwrap();
|
std::mem::replace(&mut self.connections[token.0], None).unwrap();
|
||||||
|
@ -180,9 +174,8 @@ impl<
|
||||||
let token = event.token();
|
let token = event.token();
|
||||||
let mut connection = std::mem::replace(&mut self.connections[token.0], None).unwrap();
|
let mut connection = std::mem::replace(&mut self.connections[token.0], None).unwrap();
|
||||||
if let RequestState::Outgoing(response) = connection.state {
|
if let RequestState::Outgoing(response) = connection.state {
|
||||||
let response_string = response.to_string();
|
let bytes = response.to_bytes();
|
||||||
let bytes = response_string.as_bytes();
|
connection.stream.write_all(&bytes).unwrap();
|
||||||
connection.stream.write_all(bytes).unwrap();
|
|
||||||
} else {
|
} else {
|
||||||
info!("Received write event for non-outgoing connection")
|
info!("Received write event for non-outgoing connection")
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue