rust_asio 0.6.0

Asynchronous I/O library
Documentation
use prelude::{SocketOption, GetSocketOption};
use ffi::{self, AsRawFd, SOL_SOCKET, SO_ERROR, getsockopt};

use std::io;
use std::mem;
use std::fmt;
use errno::{Errno, errno};

#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Debug)]
pub struct ErrCode(Errno);

impl fmt::Display for ErrCode {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

pub const READY: ErrCode = ErrCode(Errno(0));
pub const EINTR: ErrCode = ErrCode(Errno(ffi::EINTR));
pub const EINPROGRESS: ErrCode = ErrCode(Errno(ffi::EINPROGRESS));
pub const ECANCELED: ErrCode = ErrCode(Errno(ffi::ECANCELED));
pub const EAGAIN: ErrCode = ErrCode(Errno(ffi::EAGAIN));
pub const EWOULDBLOCK: ErrCode = ErrCode(Errno(ffi::EWOULDBLOCK));
pub const EAFNOSUPPORT: ErrCode = ErrCode(Errno(ffi::EAFNOSUPPORT));

pub fn last_error() -> ErrCode {
    ErrCode(errno())
}

impl From<ErrCode> for io::Error {
    fn from(ec: ErrCode) -> io::Error {
        debug_assert!((ec.0).0 != 0);
        io::Error::from_raw_os_error(unsafe { mem::transmute( (ec.0).0 ) })
    }
}

pub fn eof() -> io::Error {
    io::Error::new(io::ErrorKind::UnexpectedEof, "End of file")
}

pub fn invalid_argument() -> io::Error {
    io::Error::new(io::ErrorKind::Other, "Invalid argument")
}

pub fn write_zero() -> io::Error {
    io::Error::new(io::ErrorKind::WriteZero, "Write zero")
}

pub fn host_not_found() -> io::Error {
    io::Error::new(io::ErrorKind::Other, "Host not found")
}

#[derive(Default, Clone)]
struct Error(i32);

impl<P> SocketOption<P> for Error {
    type Data = i32;

    fn level(&self, _: &P) -> i32 { SOL_SOCKET }

    fn name(&self, _: &P) -> i32 { SO_ERROR }
}

impl<P> GetSocketOption<P> for Error {
    fn data_mut(&mut self) -> &mut Self::Data {
        &mut self.0
    }
}

pub fn sock_error<T>(t: &T) -> ErrCode
    where T: AsRawFd,
{
    let ec = match getsockopt(t, &()) {
        Ok(Error(ec)) => ec,
        Err(err) => err.raw_os_error().unwrap_or_default(),
    };
    ErrCode(Errno(unsafe { mem::transmute(ec) }))
}