use std::collections::HashSet;
use serde::Deserialize;
#[derive(Debug)]
pub struct TestFixtureSuppressions {
exact: HashSet<String>,
substrings: Vec<&'static str>,
}
#[derive(Debug, Deserialize)]
struct SuppressionFile {
#[allow(dead_code)]
schema_version: u32,
#[serde(default)]
exact: Vec<ExactEntry>,
#[serde(default)]
substring: Vec<SubstringEntry>,
}
#[derive(Debug, Deserialize)]
struct ExactEntry {
credential: String,
#[allow(dead_code)]
service: Option<String>,
#[allow(dead_code)]
source: Option<String>,
}
#[derive(Debug, Deserialize)]
struct SubstringEntry {
needle: String,
}
const BUNDLED_TOML: &str = include_str!("../data/suppressions/test-fixtures.toml");
impl TestFixtureSuppressions {
#[must_use]
pub fn bundled() -> Self {
let parsed: SuppressionFile = match toml::from_str(BUNDLED_TOML) {
Ok(p) => p,
Err(e) => {
tracing::warn!(
error = %e,
"bundled test-fixtures.toml failed to parse; \
falling back to empty suppression set"
);
return Self::empty();
}
};
let exact: HashSet<String> = parsed.exact.into_iter().map(|e| e.credential).collect();
let substrings: Vec<&'static str> = parsed
.substring
.into_iter()
.map(|s| Box::leak(s.needle.into_boxed_str()) as &'static str)
.collect();
Self { exact, substrings }
}
#[must_use]
pub fn empty() -> Self {
Self {
exact: HashSet::new(),
substrings: Vec::new(),
}
}
#[must_use]
pub fn suppresses(&self, cred: &str) -> bool {
if self.exact.contains(cred) {
return true;
}
for needle in &self.substrings {
if cred.contains(needle) {
return true;
}
}
false
}
#[must_use]
pub fn exact_count(&self) -> usize {
self.exact.len()
}
}