use std::collections::HashMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Module {
Http,
File,
Cmd,
Email,
Kv,
Crypto,
Jwt,
Time,
Id,
Text,
Decimal,
Money,
Json,
Regex,
Codec,
List,
Map,
Diff,
Url,
Validate,
Color,
Unit,
DateRange,
Desensitize,
Filter,
Tree,
System,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum AuditLevel {
Silent,
Summary,
Full,
FullWithPayload {
max_bytes: usize,
},
}
#[derive(Debug, Clone)]
pub struct AuditConfig {
levels: HashMap<Module, AuditLevel>,
default_io_level: AuditLevel,
default_compute_level: AuditLevel,
}
impl AuditConfig {
pub fn new(io_level: AuditLevel, compute_level: AuditLevel) -> Self {
Self {
levels: HashMap::new(),
default_io_level: io_level,
default_compute_level: compute_level,
}
}
pub fn silent_all() -> Self {
Self {
levels: HashMap::new(),
default_io_level: AuditLevel::Silent,
default_compute_level: AuditLevel::Silent,
}
}
pub fn production() -> Self {
let mut cfg = Self {
levels: HashMap::new(),
default_io_level: AuditLevel::Full,
default_compute_level: AuditLevel::Silent,
};
cfg.levels.insert(Module::Crypto, AuditLevel::Summary);
cfg.levels.insert(Module::Jwt, AuditLevel::Summary);
cfg
}
pub fn focus_on(module: Module) -> Self {
let mut cfg = Self::silent_all();
cfg.levels.insert(module, AuditLevel::Full);
cfg
}
pub fn focus_on_many(modules: &[Module]) -> Self {
let mut cfg = Self::silent_all();
for m in modules {
cfg.levels.insert(*m, AuditLevel::Full);
}
cfg
}
pub fn io_only() -> Self {
Self {
levels: HashMap::new(),
default_io_level: AuditLevel::Full,
default_compute_level: AuditLevel::Silent,
}
}
pub fn verbose_all() -> Self {
Self {
levels: HashMap::new(),
default_io_level: AuditLevel::Full,
default_compute_level: AuditLevel::Full,
}
}
pub fn enable(mut self, module: Module, level: AuditLevel) -> Self {
self.levels.insert(module, level);
self
}
pub fn silence(mut self, module: Module) -> Self {
self.levels.insert(module, AuditLevel::Silent);
self
}
pub fn level_for(&self, module: Module) -> AuditLevel {
if let Some(&level) = self.levels.get(&module) {
return level;
}
if Self::is_io_module(module) {
self.default_io_level
} else {
self.default_compute_level
}
}
pub fn is_active(&self, module: Module) -> bool {
self.level_for(module) != AuditLevel::Silent
}
fn is_io_module(module: Module) -> bool {
matches!(
module,
Module::Http
| Module::File
| Module::Cmd
| Module::Email
| Module::Kv
| Module::Crypto
| Module::Jwt
)
}
}
impl Default for AuditConfig {
fn default() -> Self {
Self::production()
}
}