Move Channel
into its own module and test it.
This commit is contained in:
parent
37e5cc8ec0
commit
2de221e166
2 changed files with 108 additions and 64 deletions
105
src/channel.rs
Normal file
105
src/channel.rs
Normal file
|
@ -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<RefCell<Inner>>,
|
||||
}
|
||||
|
||||
struct Inner {
|
||||
v: Vec<u8>,
|
||||
read_pos: usize,
|
||||
}
|
||||
|
||||
/// Implements `io::Read`, returning data previously written to a
|
||||
/// `Writer` instance from the same `Channel`.
|
||||
pub struct Reader {
|
||||
inner: Rc<RefCell<Inner>>,
|
||||
}
|
||||
|
||||
/// Implements `io::Write`, writing data to an underlying `Channel`.
|
||||
pub struct Writer {
|
||||
inner: Rc<RefCell<Inner>>,
|
||||
}
|
||||
|
||||
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<usize> {
|
||||
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<usize> {
|
||||
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]);
|
||||
}
|
||||
}
|
67
src/lib.rs
67
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<R: Read> Receiver<R> {
|
|||
|
||||
#[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<Inner>,
|
||||
}
|
||||
|
||||
struct Inner {
|
||||
_v: Vec<u8>,
|
||||
_read_pos: usize,
|
||||
}
|
||||
|
||||
pub struct Reader {
|
||||
_inner: Rc<Inner>,
|
||||
}
|
||||
|
||||
pub struct Writer {
|
||||
_inner: Rc<Inner>,
|
||||
}
|
||||
|
||||
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<usize> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for Writer {
|
||||
fn write(&mut self, _buf: &[u8]) -> Result<usize> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue