use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use crate::issue::Issue;
use crate::issue::IssueSeverity;
pub mod annotation;
pub mod builder;
pub mod error;
pub mod issue;
pub type ReportCollection<'a> = Vec<&'a Report>;
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct ReportFooter {
pub message: String,
pub notes: Vec<String>,
pub summary: bool,
}
#[derive(Debug, PartialEq, Eq, Clone, Deserialize, Serialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct Report {
pub issues: Vec<Issue>,
pub footer: Option<ReportFooter>,
}
pub trait Reportable {
fn to_reports(&self) -> Vec<&Report>;
}
impl Report {
pub fn new() -> Self {
Self {
issues: vec![],
footer: None,
}
}
#[must_use]
pub fn with_issue(mut self, issue: Issue) -> Self {
self.issues.push(issue);
self
}
#[must_use]
pub fn with_footer(mut self, footer: ReportFooter) -> Self {
self.footer = Some(footer);
self
}
pub fn severity(&self) -> Option<IssueSeverity> {
self.issues.iter().map(|issue| issue.severity).max()
}
}
impl Default for Report {
fn default() -> Self {
Self::new()
}
}
impl std::fmt::Display for Report {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for issue in &self.issues {
writeln!(f, "{issue}")?;
}
Ok(())
}
}
impl From<Issue> for Report {
fn from(val: Issue) -> Self {
Report {
issues: vec![val],
footer: None,
}
}
}
#[doc(hidden)]
impl<E: std::error::Error> From<E> for Report {
fn from(error: E) -> Self {
Report::new().with_issue(error.into())
}
}
impl ReportFooter {
pub fn new<M: Into<String>>(message: M) -> Self {
Self {
message: message.into(),
notes: vec![],
summary: true,
}
}
#[must_use]
pub fn with_note<S: Into<String>>(mut self, note: S) -> Self {
self.notes.push(note.into());
self
}
#[must_use]
pub fn with_summary(mut self, enabled: bool) -> Self {
self.summary = enabled;
self
}
}
impl Reportable for Report {
fn to_reports(&self) -> Vec<&Report> {
vec![self]
}
}
impl Reportable for ReportCollection<'_> {
fn to_reports(&self) -> Vec<&Report> {
self.to_vec()
}
}