use crates::git_workarea::CommitId;
use commit::{Commit, Content, Topic};
use context::CheckGitContext;
use error::Result;
#[derive(Debug, Default)]
pub struct CheckResult {
warnings: Vec<String>,
alerts: Vec<String>,
errors: Vec<String>,
temporary: bool,
allow: bool,
pass: bool,
}
pub enum Severity {
Warning,
Error,
Alert {
blocking: bool,
},
}
impl CheckResult {
pub fn new() -> Self {
Self {
warnings: vec![],
alerts: vec![],
errors: vec![],
temporary: false,
allow: false,
pass: true,
}
}
pub fn add_message<S>(&mut self, severity: Severity, message: S) -> &mut Self
where S: ToString,
{
match severity {
Severity::Warning => &mut self.warnings,
Severity::Error => {
self.pass = false;
&mut self.errors
},
Severity::Alert { blocking } => {
if blocking {
self.pass = false;
}
&mut self.alerts
},
}.push(message.to_string());
self
}
pub fn add_warning<S: ToString>(&mut self, warning: S) -> &mut Self {
self.add_message(Severity::Warning, warning.to_string())
}
pub fn add_alert<S: ToString>(&mut self, alert: S, should_block: bool) -> &mut Self {
self.add_message(Severity::Alert { blocking: should_block }, alert.to_string())
}
pub fn add_error<S: ToString>(&mut self, error: S) -> &mut Self {
self.add_message(Severity::Error, error.to_string())
}
pub fn make_temporary(&mut self) -> &mut Self {
self.temporary = true;
self
}
pub fn whitelist(&mut self) -> &mut Self {
self.allow = true;
self
}
pub fn warnings(&self) -> &Vec<String> {
&self.warnings
}
pub fn alerts(&self) -> &Vec<String> {
&self.alerts
}
pub fn errors(&self) -> &Vec<String> {
&self.errors
}
pub fn temporary(&self) -> bool {
self.temporary
}
pub fn allowed(&self) -> bool {
self.allow
}
pub fn pass(&self) -> bool {
self.pass
}
pub fn combine(self, other: Self) -> Self {
Self {
warnings: self.warnings.into_iter().chain(other.warnings.into_iter()).collect(),
alerts: self.alerts.into_iter().chain(other.alerts.into_iter()).collect(),
errors: self.errors.into_iter().chain(other.errors.into_iter()).collect(),
temporary: self.temporary || other.temporary,
allow: self.allow || other.allow,
pass: self.pass && other.pass,
}
}
}
pub trait Check: Send + Sync {
fn name(&self) -> &str;
fn check(&self, ctx: &CheckGitContext, commit: &Commit) -> Result<CheckResult>;
}
pub trait BranchCheck: Send + Sync {
fn name(&self) -> &str;
fn check(&self, ctx: &CheckGitContext, commit: &CommitId) -> Result<CheckResult>;
}
pub trait TopicCheck: Send + Sync {
fn name(&self) -> &str;
fn check(&self, ctx: &CheckGitContext, topic: &Topic) -> Result<CheckResult>;
}
pub trait ContentCheck: Send + Sync {
fn name(&self) -> &str;
fn check(&self, ctx: &CheckGitContext, content: &Content) -> Result<CheckResult>;
}
impl<T> Check for T
where T: ContentCheck,
{
fn name(&self) -> &str {
self.name()
}
fn check(&self, ctx: &CheckGitContext, commit: &Commit) -> Result<CheckResult> {
self.check(ctx, commit)
}
}
impl<T> TopicCheck for T
where T: ContentCheck,
{
fn name(&self) -> &str {
self.name()
}
fn check(&self, ctx: &CheckGitContext, topic: &Topic) -> Result<CheckResult> {
self.check(ctx, topic)
}
}