use core::fmt::Debug as DebugTrait;
use std::io;
use thiserror::Error;
use crate::{checkers::RelativeUrl, uri::PathError};
use super::GenericChecker;
#[derive(Clone, Debug, PartialEq)]
pub enum CheckResult {
NoFixNeeded,
FixNeeded(String),
FixExecuted(String),
Error(String),
}
#[derive(Error, Debug, PartialEq)]
pub(crate) enum CheckDefinitionError {
#[error("invalid check definition ({0})")]
InvalidDefinition(String),
#[error("Unknown checktype ({0})")]
UnknownCheckType(String),
}
#[derive(Error, Debug)]
pub(crate) enum CheckError {
#[error("file can not be read")]
FileCanNotBeRead(#[from] io::Error),
#[error("unknown file type ({0}); do not know how to handle")]
UnknownFileType(String),
#[error("file can not be removed")]
FileCanNotBeRemoved,
#[error("file can not be written")]
FileCanNotBeWritten,
#[error("invalid file format ({0})")]
InvalidFileFormat(String),
#[error("invalid regex format ({0})")]
InvalidRegex(String),
#[error("permission not available on this system")]
PermissionsNotAccessable,
#[error("git error ({0})")]
GitError(String),
#[error("file can not be fetched")]
FetchError(#[from] PathError),
#[error("{0}")]
String(String),
#[error("executing command failed")]
CommandFailed(String),
}
pub(crate) trait CheckConstructor {
type Output;
fn from_check_table(
generic_check: GenericChecker,
value: toml_edit::Table,
) -> Result<Self::Output, CheckDefinitionError>;
}
pub(crate) trait Checker: DebugTrait {
fn checker_type(&self) -> String;
fn generic_checker(&self) -> &GenericChecker;
fn checker_object(&self) -> String;
fn list_checker(&self, enabled: bool) {
log::error!(
"{} {} - {} - {} - {:?}",
if enabled { "⬜" } else { " ✖️" },
self.generic_checker().file_with_checks.short_url_str(),
self.checker_type(),
self.checker_object(),
self.generic_checker().tags
)
}
fn print(&self, check_result: &CheckResult) {
let (check_result_str, action_message) = match check_result {
CheckResult::NoFixNeeded => ("✅", "".to_string()),
CheckResult::FixNeeded(action) => ("❌", format!(" - {action}")),
CheckResult::FixExecuted(action) => ("🔧", format!(" - {action}")),
CheckResult::Error(e) => ("🚨", format!(" - {e}")),
};
let msg = format!(
"{} {} - {} - {}{}",
check_result_str,
self.generic_checker().file_with_checks().short_url_str(),
self.checker_type(),
self.checker_object(),
action_message
);
match check_result {
CheckResult::NoFixNeeded => log::info!("{msg}"),
CheckResult::FixExecuted(_) => log::info!("{msg}"),
CheckResult::FixNeeded(_) => log::warn!("{msg}"),
CheckResult::Error(_) => log::error!("{msg}"),
}
}
fn check_(&self, fix: bool) -> Result<CheckResult, CheckError>;
fn check(&self, fix: bool) -> CheckResult {
let check_result = match self.check_(fix) {
Ok(check_result) => check_result,
Err(e) => CheckResult::Error(e.to_string()),
};
self.print(&check_result);
check_result
}
}