ev 0.1.0

Cross-platform event loop primitives for unix systems.
use std::result;
use libc;


#[cfg(target_os = "macos")]
mod inner { pub use kqueue::*; }


/// Raw file descriptors.
pub type RawFd = libc::c_int;

/// Inter-process signals.
pub type Signal = libc::c_int;

/// System call error codes.
pub type Errno = libc::c_int;

/// Specialized result type.
pub type Result<T> = result::Result<T, Errno>;


/// Dispatched events.
pub enum Event {
    Readable(RawFd),
    Writable(RawFd),
    Interrupt(Signal),
    Notified,
}


/// Polls the operating system for events.
pub struct Mux {
    inner: inner::Mux,
}

impl Mux {
    pub fn new() -> Result<Self> {
        inner::Mux::new().map(|m| Mux { inner: m })
    }

    pub fn subscribe(&mut self, event: Event) -> Result<()> {
        self.inner.subscribe(event)
    }

    pub fn unsubscribe(&mut self, event: Event) -> Result<()> {
        self.inner.unsubscribe(event)
    }

    pub fn poll<'a>(&mut self, buf: &'a mut Buffer, timeout: Option<u64>) -> Result<Iter<'a>> {
        self.inner.poll(&mut buf.inner, timeout).map(|i| Iter { inner: i })
    }
}


/// Dynamic, heap-allocated event buffer.
pub struct Buffer {
    inner: inner::Buffer,
}

impl Buffer {
    pub fn new() -> Result<Self> {
        inner::Buffer::new().map(|b| Buffer { inner: b })
    }
}


/// Event iterator.
pub struct Iter<'a> {
    inner: inner::Iter<'a>,
}

impl<'a> Iterator for Iter<'a> {
    type Item = Event;

    fn next(&mut self) -> Option<Event> {
        self.inner.next()
    }
}


/// Sends simple notifications across threads.
pub struct Notifier {
    inner: inner::Notifier,
}

impl Notifier {
    pub fn attach(mux: &mut Mux) -> Result<Notifier> {
        inner::Notifier::attach(&mut mux.inner).map(|n| Notifier { inner: n })
    }

    pub fn notify(&mut self) -> Result<()> {
        self.inner.notify()
    }
}