use std::io::{self, Error as IoError};
use super::dummy_muxer::DummyMuxer;
use futures::prelude::*;
use crate::muxing::SubstreamRef;
use crate::nodes::handled_node::{HandledNode, NodeHandler, NodeHandlerEndpoint, NodeHandlerEvent};
use std::sync::Arc;
#[derive(Debug, PartialEq, Clone)]
pub(crate) struct Handler {
pub events: Vec<InEvent>,
pub state: Option<HandlerState>,
pub next_outbound_state: Option<HandlerState>,
pub next_states: Vec<HandlerState>,
}
impl Default for Handler {
fn default() -> Self {
Handler {
events: Vec::new(),
state: None,
next_states: Vec::new(),
next_outbound_state: None,
}
}
}
#[derive(Debug, PartialEq, Clone)]
pub(crate) enum HandlerState {
Ready(NodeHandlerEvent<usize, OutEvent>),
Err,
}
#[derive(Debug, PartialEq, Clone)]
pub(crate) enum InEvent {
Custom(&'static str),
Substream(Option<usize>),
NextState,
}
#[derive(Debug, PartialEq, Clone)]
pub(crate) enum OutEvent {
Custom(&'static str),
}
pub(crate) type TestHandledNode = HandledNode<DummyMuxer, Handler>;
impl NodeHandler for Handler {
type InEvent = InEvent;
type OutEvent = OutEvent;
type Error = IoError;
type OutboundOpenInfo = usize;
type Substream = SubstreamRef<Arc<DummyMuxer>>;
fn inject_substream(
&mut self,
_: Self::Substream,
endpoint: NodeHandlerEndpoint<Self::OutboundOpenInfo>,
) {
let user_data = match endpoint {
NodeHandlerEndpoint::Dialer(user_data) => Some(user_data),
NodeHandlerEndpoint::Listener => None,
};
self.events.push(InEvent::Substream(user_data));
}
fn inject_event(&mut self, inevent: Self::InEvent) {
self.events.push(inevent.clone());
match inevent {
InEvent::Custom(s) => {
self.state = Some(HandlerState::Ready(NodeHandlerEvent::Custom(
OutEvent::Custom(s),
)))
}
InEvent::Substream(Some(user_data)) => {
self.state = Some(HandlerState::Ready(
NodeHandlerEvent::OutboundSubstreamRequest(user_data),
))
}
InEvent::NextState => {
let next_state = self.next_states.pop();
self.state = next_state
}
_ => unreachable!(),
}
}
fn poll(&mut self) -> Poll<NodeHandlerEvent<usize, OutEvent>, IoError> {
match self.state.take() {
Some(ref state) => match state {
HandlerState::Ready(event) => Ok(Async::Ready(event.clone())),
HandlerState::Err => Err(io::Error::new(io::ErrorKind::Other, "oh noes")),
},
None => Ok(Async::NotReady),
}
}
}