syslog-too 0.1.0

A small library to send log messages to syslog locally and over TCP or UDP using Rust. A continuation of the syslog crate.
Documentation
//! Defines behavior for the logger backend.

use std::fmt;
use std::fmt::Arguments;
use std::io::{self, BufWriter, Write};
use std::net::{SocketAddr, TcpStream, UdpSocket};
#[cfg(unix)]
use std::os::unix::net::{UnixDatagram, UnixStream};

pub enum LoggerBackend {
    /// Unix socket, temp file path, log file path
    #[cfg(unix)]
    Unix(UnixDatagram),
    #[cfg(not(unix))]
    Unix(()),
    #[cfg(unix)]
    UnixStream(BufWriter<UnixStream>),
    #[cfg(not(unix))]
    UnixStream(()),
    Udp(UdpSocket, SocketAddr),
    Tcp(BufWriter<TcpStream>),
}

impl Write for LoggerBackend {
    /// Sends a message directly, without any formatting
    fn write(&mut self, message: &[u8]) -> io::Result<usize> {
        match *self {
            #[cfg(unix)]
            LoggerBackend::Unix(ref dgram) => dgram.send(message),
            #[cfg(unix)]
            LoggerBackend::UnixStream(ref mut socket) => {
                let null = [0; 1];
                socket
                    .write(message)
                    .and_then(|sz| socket.write(&null).map(|_| sz))
                    .and_then(|sz| socket.flush().map(|_| sz))
            }
            LoggerBackend::Udp(ref socket, ref addr) => socket.send_to(message, addr),
            LoggerBackend::Tcp(ref mut socket) => socket
                .write(message)
                .and_then(|sz| socket.flush().map(|_| sz)),
            #[cfg(not(unix))]
            LoggerBackend::Unix(_) | LoggerBackend::UnixStream(_) => {
                Err(io::Error::other("unsupported platform"))
            }
        }
    }

    fn flush(&mut self) -> io::Result<()> {
        match *self {
            #[cfg(unix)]
            LoggerBackend::Unix(_) => Ok(()),
            #[cfg(unix)]
            LoggerBackend::UnixStream(ref mut socket) => socket.flush(),
            LoggerBackend::Udp(_, _) => Ok(()),
            LoggerBackend::Tcp(ref mut socket) => socket.flush(),
            #[cfg(not(unix))]
            LoggerBackend::Unix(_) | LoggerBackend::UnixStream(_) => {
                Err(io::Error::other("unsupported platform"))
            }
        }
    }

    fn write_fmt(&mut self, args: Arguments) -> io::Result<()> {
        match *self {
            #[cfg(unix)]
            LoggerBackend::Unix(ref dgram) => {
                let message = fmt::format(args);
                dgram.send(message.as_bytes()).map(|_| ())
            }
            #[cfg(unix)]
            LoggerBackend::UnixStream(ref mut socket) => {
                let null = [0; 1];
                socket
                    .write_fmt(args)
                    .and_then(|_| socket.write(&null).map(|_| ()))
                    .and_then(|sz| socket.flush().map(|_| sz))
            }
            LoggerBackend::Udp(ref socket, ref addr) => {
                let message = fmt::format(args);
                socket.send_to(message.as_bytes(), addr).map(|_| ())
            }
            LoggerBackend::Tcp(ref mut socket) => socket
                .write_fmt(args)
                .and_then(|sz| socket.flush().map(|_| sz)),
            #[cfg(not(unix))]
            LoggerBackend::Unix(_) | LoggerBackend::UnixStream(_) => {
                Err(io::Error::other("unsupported platform"))
            }
        }
    }
}