use anyhow::Result;
use derive_builder::Builder;
use serde::Serialize;
use crate::cli::Rule;
#[derive(PartialEq, Eq, Hash, Serialize, Builder)]
#[allow(missing_docs)]
pub struct Secret {
pub secret_type: String,
pub data: String,
}
pub trait Handler: Send + Sync + 'static {
fn handle(&self, text: &str) -> Result<Vec<Secret>>;
}
pub struct RegexHandler {
rules: Vec<Rule>,
}
impl RegexHandler {
pub fn new(rules: Vec<Rule>) -> Result<Self> {
(!rules.is_empty())
.then_some(())
.ok_or(anyhow::anyhow!("no rule specified"))?;
Ok(Self { rules })
}
}
impl Handler for RegexHandler {
fn handle(&self, text: &str) -> Result<Vec<Secret>> {
Ok(self
.rules
.iter()
.flat_map(|rule| {
if rule.group {
rule.regex
.captures_iter(text)
.flat_map(|caps| {
caps.iter()
.skip(1)
.flatten()
.map(|m| Secret {
secret_type: rule.name.clone(),
data: m.as_str().to_string(),
})
.collect::<Vec<_>>()
})
.collect::<Vec<Secret>>()
} else {
rule.regex
.captures_iter(text)
.filter_map(|caps| {
caps.iter().next().flatten().map(|m| Secret {
secret_type: rule.name.clone(),
data: m.as_str().to_string(),
})
})
.collect::<Vec<Secret>>()
}
})
.collect())
}
}