use std::collections::HashSet;
use crate::action::Action;
use crate::auditable::Auditable;
use crate::config::AuditOptions;
#[derive(Clone, Debug)]
pub struct AuditConfigInfo {
pub auditable_type: String,
pub only: Option<Vec<String>>,
pub except: Option<Vec<String>>,
pub on: Vec<Action>,
pub comment_required: bool,
pub associated_with: Option<String>,
pub redacted: Vec<String>,
pub max_audits: Option<usize>,
}
impl AuditConfigInfo {
pub fn audits(&self, action: Action) -> bool {
self.on.contains(&action)
}
pub fn only_is<I, S>(&self, columns: I) -> bool
where
I: IntoIterator<Item = S>,
S: Into<String>,
{
let want: HashSet<String> = columns.into_iter().map(Into::into).collect();
match &self.only {
Some(have) => have.iter().cloned().collect::<HashSet<_>>() == want,
None => false,
}
}
pub fn except_is<I, S>(&self, columns: I) -> bool
where
I: IntoIterator<Item = S>,
S: Into<String>,
{
let want: HashSet<String> = columns.into_iter().map(Into::into).collect();
match &self.except {
Some(have) => have.iter().cloned().collect::<HashSet<_>>() == want,
None => false,
}
}
pub fn audited_columns(
&self,
all_columns: &[String],
primary_key: &str,
inheritance_column: Option<&str>,
) -> Vec<String> {
let opts = AuditOptions {
only: self.only.clone(),
except: self.except.clone(),
..AuditOptions::default()
};
let non_audited = opts.non_audited_columns(all_columns, primary_key, inheritance_column);
all_columns
.iter()
.filter(|c| !non_audited.contains(*c))
.cloned()
.collect()
}
}
pub fn audit_config<T: Auditable>() -> AuditConfigInfo {
let o = T::audit_options();
AuditConfigInfo {
auditable_type: T::auditable_type().to_string(),
only: o.only.clone(),
except: o.except.clone(),
on: o.on.clone(),
comment_required: o.comment_required,
associated_with: o.associated_with.clone(),
redacted: o.redacted.clone(),
max_audits: o.effective_max_audits(),
}
}