use crate::editor::Editor;
use console::{Style, Term};
use std::{fmt, fs::File, io};
pub trait Out: Send + Sync + 'static {
fn write(&self, buf: &[u8]) -> io::Result<usize>;
fn write_fmt(&self, args: fmt::Arguments<'_>) {
struct AsWrite<'a, T: ?Sized>(&'a T);
impl<'a, T: ?Sized + Out> io::Write for AsWrite<'a, T> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
Out::write(self.0, buf)
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
io::Write::write_fmt(&mut AsWrite(self), args).unwrap();
}
fn is_term(&self) -> bool {
false
}
fn clear_screen(&self) -> io::Result<()> {
Ok(())
}
fn read_line_with_prompt(&self, _prompt: &str) -> io::Result<String> {
Err(io::ErrorKind::Unsupported.into())
}
fn style(&self) -> Style {
Style::new().force_styling(false)
}
fn editor<'a>(&'a self, _name: &'a str) -> io::Result<Editor<'a>> {
Err(io::ErrorKind::Unsupported.into())
}
}
impl Out for Term {
fn write(&self, buf: &[u8]) -> io::Result<usize> {
io::Write::write(&mut &*self, buf)
}
fn is_term(&self) -> bool {
self.is_term()
}
fn clear_screen(&self) -> io::Result<()> {
(&*self).clear_screen()
}
fn read_line_with_prompt(&self, prompt: &str) -> io::Result<String> {
self.write_str(prompt)?;
self.flush()?;
self.read_line()
}
fn style(&self) -> Style {
self.style()
}
fn editor(&self, name: &str) -> io::Result<Editor<'_>> {
Editor::new(name)
}
}
impl Out for File {
fn write(&self, buf: &[u8]) -> io::Result<usize> {
io::Write::write(&mut &*self, buf)
}
}
impl io::Write for &'_ dyn Out {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
Out::write(*self, buf)
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}