mod issue;
mod note;
mod shortcut;
mod toissue;
use std::{
process::{
ExitCode,
Termination
},
time::Instant
};
pub use toissue::ToIssue;
pub use issue::Issue;
use crate::terminal::{
TERMINAL,
Problem
};
use shortcut::Attachment;
pub use note::Note;
pub struct Report<Object: ToIssue> {
name: &'static str = "",
problems: Vec<Problem<Object>> = Vec::new()
}
impl<Object: ToIssue> Report<Object> {
#[inline]
pub fn new(name: &'static str) -> Self {return Self {
name: name,
..
}}
#[inline]
pub fn warn(&mut self, object: Object) -> () {
let problem = Problem {
chain: Vec::from([self.name]),
at: Instant::now(),
object: object
};
TERMINAL.write().error(&problem);
self.problems.push(problem);
}
#[inline]
pub unsafe fn abort<Type>(self) -> Act<Type, Object> {return Act {
problems: self.problems,
result: None
}}
#[inline]
pub fn fail<Type>(mut self, with: Object) -> Act<Type, Object> {
let problem = Problem {
chain: Vec::from([self.name]),
at: Instant::now(),
object: with
};
TERMINAL.write().error(&problem);
self.problems.push(problem);
return Act {
problems: self.problems,
result: None
}
}
#[inline]
pub fn succeed<Type>(self, value: Type) -> Act<Type, Object> {return Act {
problems: self.problems,
result: Some(value)
}}
}
pub struct Act<Type, Object: ToIssue> {
problems: Vec<Problem<Object>>,
pub result: Option<Type>
}
impl<Object: ToIssue> Termination for Act<(), Object> {
fn report(self) -> ExitCode {return match self.result {
Some(()) => ExitCode::SUCCESS,
None => self.problems.last().unwrap().object.to_issue().code
}}
}
impl<Type, Object: ToIssue> Act<Type, Object> {
#[inline]
pub fn attach<'valid>(self, report: &'valid mut Report<Object>) -> Attachment<'valid, Type, Object> {
for mut problem in self.problems {
problem.chain.push(report.name);
report.problems.push(problem);
};
report.problems.sort_by(|first, second| first.at.cmp(&second.at));
return Attachment {
report: Some(report),
result: self.result
}
}
}