use std::{io, io::IsTerminal, str::FromStr};
use crate::{diagnostics::ShearAnalysis, output::miette::MietteRenderer};
pub mod github;
pub mod json;
pub mod miette;
#[derive(Debug, Clone, Copy, Default)]
#[non_exhaustive]
pub enum OutputFormat {
#[default]
Auto,
Json,
GitHub,
}
impl OutputFormat {
#[must_use]
pub fn resolve(self) -> Self {
if matches!(self, Self::Auto) && std::env::var_os("GITHUB_ACTIONS").is_some() {
Self::GitHub
} else {
self
}
}
}
impl FromStr for OutputFormat {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"auto" => Ok(Self::Auto),
"json" => Ok(Self::Json),
"github" => Ok(Self::GitHub),
_ => Err(format!("unknown format: {s}, expected: auto, json, github")),
}
}
}
#[derive(Debug, Clone, Copy, Default)]
#[non_exhaustive]
pub enum ColorMode {
#[default]
Auto,
Always,
Never,
}
impl ColorMode {
#[must_use]
pub fn enabled(self) -> bool {
match self {
Self::Always => true,
Self::Never => false,
Self::Auto => {
if std::env::var_os("NO_COLOR").is_some() {
return false;
}
std::io::stdout().is_terminal()
}
}
}
}
impl FromStr for ColorMode {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"auto" => Ok(Self::Auto),
"always" => Ok(Self::Always),
"never" => Ok(Self::Never),
_ => Err(format!("unknown color option: {s}, expected one of: auto, always, never")),
}
}
}
pub struct Renderer<W> {
writer: W,
format: OutputFormat,
color: bool,
}
impl<W: io::Write> Renderer<W> {
pub const fn new(writer: W, format: OutputFormat, color: bool) -> Self {
Self { writer, format, color }
}
pub fn render(&mut self, analysis: &ShearAnalysis) -> io::Result<()> {
match self.format {
OutputFormat::Auto => {
let mut renderer = MietteRenderer::new(&mut self.writer, self.color);
renderer.render(analysis)
}
OutputFormat::Json => {
let mut renderer = json::JsonRenderer::new(&mut self.writer);
renderer.render(analysis)
}
OutputFormat::GitHub => {
let mut renderer = github::GitHubRenderer::new(&mut self.writer);
renderer.render(analysis)
}
}
}
}