use std::io::{IsTerminal, Stdout, Write};
use crate::output::{add_ext, format_by_ext};
#[derive(Debug)]
pub struct Buffer<'a> {
buf: String,
stdout: &'a mut Stdout,
is_terminal: bool,
filename: String,
content_type: String,
}
impl<'a> Buffer<'a> {
pub fn new(
stdout: &'a mut Stdout,
filename: impl ToString,
content_type: impl ToString,
) -> Self {
let is_terminal = stdout.is_terminal();
Self {
buf: String::new(),
stdout, is_terminal,
filename: filename.to_string(),
content_type: content_type.to_string(),
}
}
}
impl Write for Buffer<'_> {
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
let size = buf.len();
let chunk = String::from_utf8_lossy(buf);
if self.is_terminal {
self.buf += &chunk;
} else {
write!(self.stdout, "{}", chunk).unwrap();
}
Ok(size)
}
}
impl Drop for Buffer<'_> {
fn drop(&mut self) {
if self.is_terminal {
let filename = add_ext(&self.filename, &self.content_type);
format_by_ext(&self.buf, &filename, self.stdout).unwrap();
}
}
}