kind_report/report/mode/
mod.rs

1use std::{fmt::Write, path::Path};
2
3use super::code::FileMarkers;
4use crate::{
5    data::{Diagnostic, DiagnosticFrame, FileCache, Log},
6    RenderConfig,
7};
8
9pub mod classic;
10pub mod compact;
11
12// Just a type synonym to make it easier to read.
13pub type Res = std::fmt::Result;
14
15// -----------------------------------------------------------------
16// Some abstract data types based on Haskell. These types are useful
17// for setting some modes on the report.
18// -----------------------------------------------------------------
19
20/// Classical mode is the default mode for the report. It's made to
21/// be easy to read and understand.
22pub enum Classic {}
23
24/// Compact mode is made to be more compact and easy to parse by some
25/// LLM.
26pub enum Compact {}
27
28/// The enum of all of the modes so we can choose
29#[derive(Debug, Clone, Copy)]
30pub enum Mode {
31    Classic,
32    Compact,
33}
34
35// Utilities
36
37/// Utility for easier renders
38pub(crate) struct CodeBlock<'a> {
39    pub code: &'a str,
40    pub path: &'a Path,
41    pub markers: &'a FileMarkers,
42}
43
44/// A type class for renderable error reports and messages. It's useful
45/// to change easily things without problems.
46pub trait Renderable<T> {
47    fn render(&self, fmt: &mut dyn Write, cache: &dyn FileCache, config: &RenderConfig) -> Res;
48}
49
50impl<T, E> Renderable<T> for Vec<E>
51where
52    E: Renderable<T>,
53{
54    fn render(&self, fmt: &mut dyn Write, cache: &dyn FileCache, config: &RenderConfig) -> Res {
55        for elem in self {
56            elem.render(fmt, cache, config)?;
57        }
58        Ok(())
59    }
60}
61
62impl<T> Renderable<T> for Box<dyn Diagnostic>
63where
64    DiagnosticFrame: Renderable<T>,
65{
66    fn render(&self, fmt: &mut dyn Write, cache: &dyn FileCache, config: &RenderConfig) -> Res {
67        Renderable::<T>::render(&self.to_diagnostic_frame(config), fmt, cache, config)
68    }
69}
70
71pub trait Report
72where
73    Self: Renderable<Classic> + Renderable<Compact>,
74{
75    fn render(&self, fmt: &mut dyn Write, cache: &dyn FileCache, config: &RenderConfig) -> Res {
76        match config.mode {
77            Mode::Classic => Renderable::<Classic>::render(self, fmt, cache, config),
78            Mode::Compact => Renderable::<Compact>::render(self, fmt, cache, config),
79        }
80    }
81}
82
83impl Report for Box<dyn Diagnostic> {}
84impl Report for Log {}