use std::{fmt::Write, path::Path};
use super::code::FileMarkers;
use crate::{
data::{Diagnostic, DiagnosticFrame, FileCache, Log},
RenderConfig,
};
pub mod classic;
pub mod compact;
pub type Res = std::fmt::Result;
pub enum Classic {}
pub enum Compact {}
#[derive(Debug, Clone, Copy)]
pub enum Mode {
Classic,
Compact,
}
pub(crate) struct CodeBlock<'a> {
pub code: &'a str,
pub path: &'a Path,
pub markers: &'a FileMarkers,
}
pub trait Renderable<T> {
fn render(&self, fmt: &mut dyn Write, cache: &dyn FileCache, config: &RenderConfig) -> Res;
}
impl<T, E> Renderable<T> for Vec<E>
where
E: Renderable<T>,
{
fn render(&self, fmt: &mut dyn Write, cache: &dyn FileCache, config: &RenderConfig) -> Res {
for elem in self {
elem.render(fmt, cache, config)?;
}
Ok(())
}
}
impl<T> Renderable<T> for Box<dyn Diagnostic>
where
DiagnosticFrame: Renderable<T>,
{
fn render(&self, fmt: &mut dyn Write, cache: &dyn FileCache, config: &RenderConfig) -> Res {
Renderable::<T>::render(&self.to_diagnostic_frame(config), fmt, cache, config)
}
}
pub trait Report
where
Self: Renderable<Classic> + Renderable<Compact>,
{
fn render(&self, fmt: &mut dyn Write, cache: &dyn FileCache, config: &RenderConfig) -> Res {
match config.mode {
Mode::Classic => Renderable::<Classic>::render(self, fmt, cache, config),
Mode::Compact => Renderable::<Compact>::render(self, fmt, cache, config),
}
}
}
impl Report for Box<dyn Diagnostic> {}
impl Report for Log {}