use futures::prelude::*;
use futures::{
future::{self, FutureResult},
stream,
};
use std::io;
use crate::{Multiaddr, PeerId, Transport, transport::{ListenerEvent, TransportError}};
use crate::tests::dummy_muxer::DummyMuxer;
#[derive(Debug, PartialEq, Clone)]
pub(crate) enum ListenerState {
Ok(Async<Option<ListenerEvent<(PeerId, DummyMuxer)>>>),
Error,
Events(Vec<ListenerEvent<(PeerId, DummyMuxer)>>)
}
#[derive(Debug, PartialEq, Clone)]
pub(crate) struct DummyTransport {
listener_state: ListenerState,
next_peer_id: Option<PeerId>,
dial_should_fail: bool,
}
impl DummyTransport {
pub(crate) fn new() -> Self {
DummyTransport {
listener_state: ListenerState::Ok(Async::NotReady),
next_peer_id: None,
dial_should_fail: false,
}
}
pub(crate) fn set_initial_listener_state(&mut self, state: ListenerState) {
self.listener_state = state;
}
pub(crate) fn set_next_peer_id(&mut self, peer_id: &PeerId) {
self.next_peer_id = Some(peer_id.clone());
}
pub(crate) fn make_dial_fail(&mut self) {
self.dial_should_fail = true;
}
}
impl Transport for DummyTransport {
type Output = (PeerId, DummyMuxer);
type Error = io::Error;
type Listener = Box<dyn Stream<Item=ListenerEvent<Self::ListenerUpgrade>, Error=io::Error> + Send>;
type ListenerUpgrade = FutureResult<Self::Output, io::Error>;
type Dial = Box<dyn Future<Item = Self::Output, Error = io::Error> + Send>;
fn listen_on(self, addr: Multiaddr) -> Result<Self::Listener, TransportError<Self::Error>>
where
Self: Sized,
{
match self.listener_state {
ListenerState::Ok(state) => match state {
Async::NotReady => Ok(Box::new(stream::poll_fn(|| Ok(Async::NotReady)))),
Async::Ready(Some(event)) => Ok(Box::new(stream::poll_fn(move || {
Ok(Async::Ready(Some(event.clone().map(future::ok))))
}))),
Async::Ready(None) => Ok(Box::new(stream::empty()))
},
ListenerState::Error => Err(TransportError::MultiaddrNotSupported(addr)),
ListenerState::Events(events) =>
Ok(Box::new(stream::iter_ok(events.into_iter().map(|e| e.map(future::ok)))))
}
}
fn dial(self, _addr: Multiaddr) -> Result<Self::Dial, TransportError<Self::Error>>
where
Self: Sized,
{
let peer_id = if let Some(peer_id) = self.next_peer_id {
peer_id
} else {
PeerId::random()
};
let fut =
if self.dial_should_fail {
let err_string = format!("unreachable host error, peer={:?}", peer_id);
future::err(io::Error::new(io::ErrorKind::Other, err_string))
} else {
future::ok((peer_id, DummyMuxer::new()))
};
Ok(Box::new(fut))
}
}