1use std::cmp::min;
2use std::io::{self, Read, Write};
3use std::sync::{Arc, Mutex};
4
5use netbuf::RangeArgument;
6use futures::{Poll, Async};
7use tokio_io::{AsyncRead, AsyncWrite};
8
9pub struct Mock;
13
14impl Read for Mock {
15 fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
16 Err(io::Error::new(io::ErrorKind::WouldBlock, "No read"))
17 }
18}
19
20impl Write for Mock {
21 fn write(&mut self, _buf: &[u8]) -> io::Result<usize> {
22 Err(io::Error::new(io::ErrorKind::WouldBlock, "No write"))
23 }
24 fn flush(&mut self) -> io::Result<()> {
25 Err(io::Error::new(io::ErrorKind::WouldBlock, "No flush"))
26 }
27}
28
29impl AsyncRead for Mock {}
30impl AsyncWrite for Mock {
31 fn shutdown(&mut self) -> Poll<(), io::Error> {
32 Ok(Async::NotReady)
33 }
34}
35
36
37#[derive(Clone)]
41pub struct MockData {
42 input: Arc<Mutex<Vec<u8>>>,
43 output: Arc<Mutex<Vec<u8>>>,
44}
45
46impl MockData {
47 pub fn new() -> MockData {
49 MockData {
50 input: Arc::new(Mutex::new(Vec::new())),
51 output: Arc::new(Mutex::new(Vec::new())),
52 }
53 }
54 pub fn add_input<D: AsRef<[u8]>>(&self, data: D) {
57 self.input.lock().unwrap().extend(data.as_ref())
58 }
59
60 pub fn output<T: Into<RangeArgument>>(&self, range: T) -> Vec<u8> {
69 let buf = self.output.lock().unwrap();
70 use netbuf::RangeArgument::*;
71 match range.into() {
72 RangeTo(x) => buf[..x].to_vec(),
73 RangeFrom(x) => buf[x..].to_vec(),
74 Range(x, y) => buf[x..y].to_vec(),
75 }
76 }
77
78 pub fn get_output(&self, num: usize) -> Vec<u8> {
83 let mut buf = self.output.lock().unwrap();
84 return buf.drain(..num).collect();
85 }
86}
87
88impl Read for MockData {
89 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
90 let mut inp = self.input.lock().unwrap();
91 let bytes = min(buf.len(), inp.len());
92 if bytes == 0 {
93 return Err(io::ErrorKind::WouldBlock.into());
94 }
95 buf[..bytes].copy_from_slice(&inp[..bytes]);
96 inp.drain(..bytes);
97 return Ok(bytes);
98 }
99}
100
101impl Write for MockData {
102 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
103 let mut out = self.output.lock().unwrap();
104 out.extend(buf);
105 return Ok(buf.len());
106 }
107 fn flush(&mut self) -> io::Result<()> {
108 Ok(())
109 }
110}
111
112impl AsyncRead for MockData {}
113impl AsyncWrite for MockData {
114 fn shutdown(&mut self) -> Poll<(), io::Error> {
115 if self.output.lock().unwrap().len() > 0 {
116 Ok(Async::NotReady)
117 } else {
118 Ok(Async::Ready(()))
119 }
120 }
121}
122
123
124#[cfg(test)]
125mod test {
126
127 use {IoBuf, Mock, MockData};
128
129 #[test]
130 fn mock() {
131 let mut buf = IoBuf::new(Mock);
132 buf.read().ok();
133 assert_eq!(&buf.in_buf[..], b"");
134 buf.out_buf.extend(b"hello");
135 assert_eq!(&buf.out_buf[..], b"hello");
136 buf.flush().ok(); assert_eq!(&buf.out_buf[..], b"hello");
138 }
139
140 #[test]
141 fn mock_data() {
142 let data = MockData::new();
143 let mut buf = IoBuf::new(data.clone());
144 buf.read().ok();
145 assert_eq!(&buf.in_buf[..], b"");
146 data.add_input("test me");
147 buf.read().ok();
148 assert_eq!(&buf.in_buf[..], b"test me");
149
150 buf.out_buf.extend(b"hello");
151 assert_eq!(&buf.out_buf[..], b"hello");
152 buf.flush().ok();
153 assert_eq!(&buf.out_buf[..], b"");
154 assert_eq!(&data.output(..), b"hello");
155 }
156
157}