From 2de221e1663dc050f3c4be35c9ac26475789069a Mon Sep 17 00:00:00 2001 From: Alex Helfet Date: Thu, 21 Dec 2017 03:07:57 +0000 Subject: [PATCH] Move `Channel` into its own module and test it. --- src/channel.rs | 105 +++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 67 ++----------------------------- 2 files changed, 108 insertions(+), 64 deletions(-) create mode 100644 src/channel.rs diff --git a/src/channel.rs b/src/channel.rs new file mode 100644 index 0000000..1876dc6 --- /dev/null +++ b/src/channel.rs @@ -0,0 +1,105 @@ +//! Vec-backed FIFO buffer of bytes for testing. + +use std::cell::RefCell; +use std::io::{Read, Result, Write}; +use std::rc::Rc; + +/// Entry point for the module that can construct multiple `Reader` +/// and `Writer` endpoints using the same backing store. +pub struct Channel { + inner: Rc>, +} + +struct Inner { + v: Vec, + read_pos: usize, +} + +/// Implements `io::Read`, returning data previously written to a +/// `Writer` instance from the same `Channel`. +pub struct Reader { + inner: Rc>, +} + +/// Implements `io::Write`, writing data to an underlying `Channel`. +pub struct Writer { + inner: Rc>, +} + +impl Channel { + /// Construct a new `Channel`. + pub fn new() -> Channel { + Channel { + inner: Rc::new(RefCell::new(Inner { + v: Vec::new(), + read_pos: 0 + })) + } + } + + /// Construct a new `Reader` for this `Channel`. + pub fn reader(&self) -> Reader { + Reader { + inner: self.inner.clone(), + } + } + + /// Construct a new `Writer` for this `Channel`. + pub fn writer(&self) -> Writer { + Writer { + inner: self.inner.clone(), + } + } +} + +impl Read for Reader { + fn read(&mut self, buf: &mut [u8]) -> Result { + let mut inner = self.inner.borrow_mut(); + let pos = inner.read_pos; + assert!(inner.v.len() >= pos); + + let left = inner.v.len() - pos; + let len = buf.len().min(left); + + buf[0..len].copy_from_slice(&inner.v[pos..pos + len]); + let new_pos = pos + len; + assert!(inner.v.len() >= new_pos); + inner.read_pos = new_pos; + + Ok(len) + } +} + +impl Write for Writer { + fn write(&mut self, buf: &[u8]) -> Result { + self.inner.borrow_mut().v.extend_from_slice(buf); + Ok(buf.len()) + } + + fn flush(&mut self) -> Result<()> { + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use std::io::{Read, Write}; + use super::Channel; + + #[test] + fn ok() { + let c = Channel::new(); + let mut tx = c.writer(); + let mut rx = c.reader(); + + let mut buf = [0u8; 5]; + + assert_eq!(rx.read(&mut buf).unwrap(), 0); + + assert_eq!(tx.write(&[1, 2, 3]).unwrap(), 3); + assert_eq!(rx.read(&mut buf[0..1]).unwrap(), 1); + assert_eq!(buf, [1, 0, 0, 0, 0]); + assert_eq!(rx.read(&mut buf[1..5]).unwrap(), 2); + assert_eq!(buf, [1, 2, 3, 0, 0]); + } +} diff --git a/src/lib.rs b/src/lib.rs index c292d96..12380b0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,6 +17,8 @@ #[macro_use] extern crate error_chain; +pub mod channel; + pub mod error; use error::{Result}; use std::io::{Read, Write}; @@ -57,6 +59,7 @@ impl Receiver { #[cfg(test)] mod tests { + use channel::Channel; use std::io::{Read, Write}; use super::{Receiver, Sender}; @@ -75,68 +78,4 @@ mod tests { let rx = Receiver::new(c.reader()); (tx, rx) } - - use self::channel::Channel; - - mod channel { - use std::io::{Read, Result, Write}; - use std::rc::Rc; - - /// A Vec-backed buffer that can be read from and written to. - pub struct Channel { - inner: Rc, - } - - struct Inner { - _v: Vec, - _read_pos: usize, - } - - pub struct Reader { - _inner: Rc, - } - - pub struct Writer { - _inner: Rc, - } - - impl Channel { - pub fn new() -> Channel { - Channel { - inner: Rc::new(Inner { - _v: Vec::new(), - _read_pos: 0 - }) - } - } - - pub fn reader(&self) -> Reader { - Reader { - _inner: self.inner.clone(), - } - } - - pub fn writer(&self) -> Writer { - Writer { - _inner: self.inner.clone(), - } - } - } - - impl Read for Reader { - fn read(&mut self, _buf: &mut [u8]) -> Result { - unimplemented!() - } - } - - impl Write for Writer { - fn write(&mut self, _buf: &[u8]) -> Result { - unimplemented!() - } - - fn flush(&mut self) -> Result<()> { - unimplemented!() - } - } - } }