use crate::pager::{Bat, PagerHandleWriter};
use std::io::{Read, Write};
struct StdoutOutput;
struct BatOutput(String);
struct WriteOutput<W>(W);
pub(crate) fn output_to_stdout() -> impl CopyFromReader + Output {
StdoutOutput
}
pub(crate) fn output_to_bat(language: &str) -> impl CopyFromReader + Output {
BatOutput(language.to_string())
}
#[allow(dead_code)]
pub(crate) fn output_to_write<W: Write>(write: W) -> impl CopyFromReader {
WriteOutput(write)
}
pub(crate) trait CopyFromReader {
fn copy_from_reader<R: Read>(&mut self, reader: R) -> crate::error::Result<()>;
}
impl CopyFromReader for StdoutOutput {
fn copy_from_reader<R: Read>(&mut self, mut reader: R) -> crate::error::Result<()> {
let mut stdout = std::io::stdout().lock();
std::io::copy(&mut reader, &mut stdout)?;
Ok(())
}
}
impl CopyFromReader for BatOutput {
fn copy_from_reader<R: Read>(&mut self, reader: R) -> crate::error::Result<()> {
let handle = Bat::new_handle(&self.0)?;
handle.handle_read(reader)?;
Ok(())
}
}
impl<W: Write> CopyFromReader for WriteOutput<W> {
fn copy_from_reader<R: Read>(&mut self, mut reader: R) -> crate::error::Result<()> {
std::io::copy(&mut reader, &mut self.0)?;
Ok(())
}
}
pub(crate) trait Output {
type Writer: OutputWriter;
fn create_output_writer(&self) -> crate::error::Result<Self::Writer>
where
Self: Sized;
}
impl Output for StdoutOutput {
type Writer = std::io::StdoutLock<'static>;
fn create_output_writer(&self) -> crate::error::Result<Self::Writer> {
Ok(std::io::stdout().lock())
}
}
impl Output for BatOutput {
type Writer = PagerHandleWriter;
fn create_output_writer(&self) -> crate::error::Result<Self::Writer>
where
Self: Sized,
{
let handle = Bat::new_handle(&self.0)?;
Ok(handle.into_writer())
}
}
pub(crate) trait OutputWriter: Write {
fn wait(self) -> crate::error::Result<i32>;
}
impl OutputWriter for std::io::StdoutLock<'static> {
fn wait(self) -> crate::error::Result<i32> {
Ok(0)
}
}