rust_asio 0.1.0

Asynchronous I/O Library
Documentation
use std::io;
use std::mem;
use std::fmt;
use std::cmp;
use std::path::Path;
use std::marker::PhantomData;
use socket::*;
use ops::*;

#[derive(Clone)]
pub struct LocalEndpoint<P: Protocol> {
    sun: sockaddr_un,
    marker: PhantomData<P>,
}

impl<P: Protocol> LocalEndpoint<P> {
    pub fn new<T: AsRef<Path>>(path: T) -> io::Result<LocalEndpoint<P>> {
        match path.as_ref().to_str() {
            Some(s) if s.len() < UNIX_PATH_MAX => {
                let mut ep = LocalEndpoint {
                    sun: unsafe { mem::zeroed() },
                    marker: PhantomData,
                };
                ep.sun.sun_family = AF_LOCAL as u16;
                str2c_char(&s, &mut ep.sun.sun_path);
                Ok(ep)
            },
            _ => Err(io::Error::new(io::ErrorKind::Other, "Unsupported pathname")),
        }
    }

    pub fn path(&self) -> String {
        c_char2string(&self.sun.sun_path)
    }
}

impl<P: Protocol> AsRawSockAddr for LocalEndpoint<P> {
    fn as_raw_sockaddr(&self) -> &RawSockAddrType {
        unsafe { mem::transmute(&self.sun) }
    }

    fn as_mut_raw_sockaddr(&mut self) -> &mut RawSockAddrType {
        unsafe { mem::transmute(&mut self.sun) }
    }

    fn raw_socklen(&self) -> RawSockLenType {
        mem::size_of_val(&self.sun) as RawSockLenType
    }
}

unsafe impl<P: Protocol> Send for LocalEndpoint<P> {}

impl<P: Protocol> Eq for LocalEndpoint<P> {
}

impl<P: Protocol> PartialEq for LocalEndpoint<P> {
    fn eq(&self, other: &Self) -> bool {
        raw_sockaddr_eq(self, other)
    }
}

impl<P: Protocol> Ord for LocalEndpoint<P> {
    fn cmp(&self, other: &Self) -> cmp::Ordering {
        raw_sockaddr_cmp(self, other)
    }
}

impl<P: Protocol> PartialOrd for LocalEndpoint<P> {
    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
        Some(self.cmp(other))
    }
}

impl<P: Protocol> fmt::Display for LocalEndpoint<P> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.path())
    }
}

pub trait LocalSocket : Socket {
}

mod dgram;
pub use self::dgram::*;

mod stream;
pub use self::stream::*;

mod seq_packet;
pub use self::seq_packet::*;

#[test]
fn test_local_endpoint() {
    assert!(LocalStreamEndpoint::new("foo").unwrap() == LocalStreamEndpoint::new("foo").unwrap());
    assert!(LocalDgramEndpoint::new("").is_ok());
    let s = "01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";
    assert!(LocalSeqPacketEndpoint::new(&s[..UNIX_PATH_MAX-1]).is_ok());
    assert!(LocalSeqPacketEndpoint::new(&s[..UNIX_PATH_MAX]).is_err());
}