use futures::{Async, Future, Poll};
use mio;
use std::error;
use std::fmt;
use std::io;
use std::mem;
use std::net::SocketAddr;
use std::sync::Arc;
pub use self::tcp::{TcpListener, TcpStream};
pub use self::udp::UdpSocket;
use fiber;
use io::poll::{EventedHandle, Register};
pub mod futures {
pub use super::tcp::{Connect, Connected, TcpListenerBind};
pub use super::udp::{RecvFrom, SendTo, UdpSocketBind};
}
pub mod streams {
pub use super::tcp::Incoming;
}
mod tcp;
mod udp;
enum Bind<F, T> {
Bind(SocketAddr, F),
Registering(Register<T>),
Polled,
}
impl<F, T> Future for Bind<F, T>
where
F: FnOnce(&SocketAddr) -> io::Result<T>,
T: mio::Evented + Send + 'static,
{
type Item = Arc<EventedHandle<T>>;
type Error = io::Error;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
match mem::replace(self, Bind::Polled) {
Bind::Bind(addr, bind) => {
let socket = bind(&addr)?;
let register = assert_some!(fiber::with_current_context(|mut c| c
.poller()
.register(socket),));
*self = Bind::Registering(register);
self.poll()
}
Bind::Registering(mut future) => {
if let Async::Ready(handle) = future.poll().map_err(into_io_error)? {
Ok(Async::Ready(handle))
} else {
*self = Bind::Registering(future);
Ok(Async::NotReady)
}
}
Bind::Polled => panic!("Cannot poll Bind twice"),
}
}
}
impl<F, T> fmt::Debug for Bind<F, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Bind::Bind(addr, _) => write!(f, "Bind::Bind({:?}, _)", addr),
Bind::Registering(_) => write!(f, "Bind::Registering(_)"),
Bind::Polled => write!(f, "Bind::Polled"),
}
}
}
fn into_io_error<E: error::Error + Send + Sync + 'static>(error: E) -> io::Error {
io::Error::new(io::ErrorKind::Other, Box::new(error))
}