Use trait objects and dynamic dispatch to abstract over NetworkStream

Server and client benchmarks show that this makes very little difference
in performance and using dynamic dispatch here is significantly more ergonomic.

This also bounds NetworkStream with Send to prevent incorrect implementations.

Allows the implementation of mock streams for testing and flexibility.

Fixes #5
This commit is contained in:
Jonathan Reem
2014-09-09 14:28:06 -07:00
parent 0285fc2acc
commit 76a58940d8
5 changed files with 43 additions and 31 deletions

View File

@@ -22,7 +22,7 @@ pub trait NetworkAcceptor<S: NetworkStream>: Acceptor<S> + Clone + Send {
}
/// An abstraction over streams that a Server can utilize.
pub trait NetworkStream: Stream + Clone {
pub trait NetworkStream: Stream + Clone + Send {
/// Get the remote address of the underlying connection.
fn peer_name(&mut self) -> IoResult<SocketAddr>;
@@ -30,6 +30,19 @@ pub trait NetworkStream: Stream + Clone {
fn connect(host: &str, port: Port) -> IoResult<Self>;
}
impl Reader for Box<NetworkStream + Send> {
#[inline]
fn read(&mut self, buf: &mut [u8]) -> IoResult<uint> { self.read(buf) }
}
impl Writer for Box<NetworkStream + Send> {
#[inline]
fn write(&mut self, msg: &[u8]) -> IoResult<()> { self.write(msg) }
#[inline]
fn flush(&mut self) -> IoResult<()> { self.flush() }
}
/// A `NetworkListener` for `HttpStream`s.
pub struct HttpListener {
inner: TcpListener