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 {
#[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 {
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"))
}
}
}
}