voidio 0.1.6

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

pub trait ConsoleReceiver {
    fn send(&self, component: &dyn ConsoleSendable) -> io::Result<()>;
}

pub struct ConsoleSender {
    console: Box<dyn ConsoleReceiver>,
    format: Option<Arc<dyn Fn(&dyn ConsoleSendable) -> ConsoleMessage + Send + Sync>>,

}
impl ConsoleSender {
    pub fn new<R: ConsoleReceiver + 'static>(receiver: R) -> ConsoleSender {
        ConsoleSender {
            console: Box::new(receiver),
            format: None,
        }
    }
    pub fn set_format<F>(&mut self, formatter: F)
    where
        F: Fn(&dyn ConsoleSendable) -> ConsoleMessage + Send + Sync + 'static
    {
        self.format = Some(Arc::new(formatter));
    }

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

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

impl ConsoleReceiver for io::Stdout {
    fn send(&self, msg: &dyn ConsoleSendable) -> io::Result<()> {
        let mut stdout = stdout();
        writeln!(stdout, "{}", msg)?;
        Ok(())
    }
}

impl ConsoleReceiver for ConsoleSender {
    fn send(&self, msg: &dyn ConsoleSendable) -> io::Result<()> {
        self.console.send(msg)
    }
}