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]
|
#[macro_use]
|
||||||
extern crate error_chain;
|
extern crate error_chain;
|
||||||
|
|
||||||
|
pub mod channel;
|
||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
use error::{Result};
|
use error::{Result};
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
|
@ -57,6 +59,7 @@ impl<R: Read> Receiver<R> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use channel::Channel;
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use super::{Receiver, Sender};
|
use super::{Receiver, Sender};
|
||||||
|
|
||||||
|
@ -75,68 +78,4 @@ mod tests {
|
||||||
let rx = Receiver::new(c.reader());
|
let rx = Receiver::new(c.reader());
|
||||||
(tx, rx)
|
(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