voidio 0.1.9

VOID I/O - High-performance Cross-platform I/O for Rust.
use std::io;
use std::sync::Arc;
use crate::console::component::ConsoleSendable;
use crate::console::ConsoleMessage;
use crate::console::receiver::Console;
use std::io::{Write};

#[derive(Clone)]
pub struct ConsoleSender<T: Console + Clone + 'static> {
    target: T,
    format: Option<Arc<dyn Fn(&dyn ConsoleSendable) -> ConsoleMessage + Send + Sync>>,
    message_logging: bool,
}
impl<T: Console + Clone + 'static> ConsoleSender<T> {
    pub fn new(rx: T) -> Self {
        ConsoleSender {
            target: rx,
            format: None,
            message_logging: true,
        }
    }
    /// Enable or disable message logging
    pub fn log(&mut self, message_logging_enabled: bool) {
        self.message_logging = message_logging_enabled;
    }
    /// Set a custom log format, only effective if message logging is enabled
    pub fn log_format<F>(&mut self, formatter: F)
    where
        F: Fn(&dyn ConsoleSendable) -> ConsoleMessage + Send + Sync + 'static
    {
        self.format = Some(Arc::new(formatter));
    }

    pub fn try_send<M: ConsoleSendable>(&self, msg: M) -> io::Result<()> {
        if let Some(formatter) = &self.format {
            self.target.send(&formatter(&msg))
        } else {
            self.target.send(&msg)
        }
    }

    pub fn send<M: ConsoleSendable>(&self, msg: M) {
        if let Err(e) = self.try_send(msg) {
            eprintln!("Console send error: {}", e);
        }
    }

    pub fn send_ref<M: ConsoleSendable>(&self, msg: &M) -> io::Result<()> {
        if let Some(formatter) = &self.format {
            self.target.send(&formatter(msg))
        } else {
            self.target.send(msg)
        }
    }
}

#[derive(Clone)]
pub struct Stdout {
    inner: Arc<std::io::Stdout>
}
impl Stdout {
    pub fn writeln(&self, msg: &str) -> io::Result<()> {
        let mut handle = self.inner.lock();
        writeln!(handle, "{}", msg)
    }
}
pub fn stdout() -> Stdout {
    Stdout {
        inner: Arc::new(io::stdout())
    }
}
impl Console for Stdout {
    fn send(&self, msg: &dyn ConsoleSendable) -> io::Result<()> {
        self.writeln(&msg.to_string())
    }
}