use std::io::{self, Cursor, Write};
use std::sync::mpsc::{channel, Receiver, Sender};
use std::time::{Duration, Instant};
use serde_json::{self, Value};
use super::{Callback, Error, MessageReader, Peer, ReadError, Response, RpcObject};
pub struct DummyWriter(Sender<String>);
pub struct DummyReader(MessageReader, Receiver<String>);
#[derive(Debug, Clone)]
pub struct DummyPeer;
pub fn test_channel() -> (DummyWriter, DummyReader) {
let (tx, rx) = channel();
(DummyWriter(tx), DummyReader(MessageReader::default(), rx))
}
pub fn make_reader<S: AsRef<str>>(s: S) -> Cursor<Vec<u8>> {
Cursor::new(s.as_ref().as_bytes().to_vec())
}
impl DummyReader {
pub fn next_timeout(&mut self, timeout: Duration) -> Option<Result<RpcObject, ReadError>> {
self.1.recv_timeout(timeout).ok().map(|s| self.0.parse(&s))
}
pub fn expect_response(&mut self) -> Response {
let raw = self.next_timeout(Duration::from_secs(1)).expect("response should be received");
let val = raw.as_ref().ok().map(|v| serde_json::to_string(&v.0));
let resp = raw.map_err(|e| e.to_string()).and_then(|r| r.into_response());
match resp {
Err(msg) => panic!("Bad response: {:?}. {}", val, msg),
Ok(resp) => resp,
}
}
pub fn expect_object(&mut self) -> RpcObject {
self.next_timeout(Duration::from_secs(1)).expect("expected object").unwrap()
}
pub fn expect_rpc(&mut self, method: &str) -> RpcObject {
let obj = self
.next_timeout(Duration::from_secs(1))
.unwrap_or_else(|| panic!("expected rpc \"{}\"", method))
.unwrap();
assert_eq!(obj.get_method(), Some(method));
obj
}
pub fn expect_nothing(&mut self) {
if let Some(thing) = self.next_timeout(Duration::from_millis(500)) {
panic!("unexpected something {:?}", thing);
}
}
}
impl Write for DummyWriter {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let s = String::from_utf8(buf.to_vec()).unwrap();
self.0
.send(s)
.map_err(|err| io::Error::new(io::ErrorKind::Other, format!("{:?}", err)))
.map(|_| buf.len())
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
impl Peer for DummyPeer {
fn box_clone(&self) -> Box<dyn Peer> {
Box::new(self.clone())
}
fn send_rpc_notification(&self, _method: &str, _params: &Value) {}
fn send_rpc_request_async(&self, _method: &str, _params: &Value, f: Box<dyn Callback>) {
f.call(Ok("dummy peer".into()))
}
fn send_rpc_request(&self, _method: &str, _params: &Value) -> Result<Value, Error> {
Ok("dummy peer".into())
}
fn request_is_pending(&self) -> bool {
false
}
fn schedule_idle(&self, _token: usize) {}
fn schedule_timer(&self, _time: Instant, _token: usize) {}
}