use serde::Deserialize;
use std::sync::OnceLock;
const SNAPSHOT: &str = include_str!("../../data/loldrivers.json");
#[derive(Debug, Clone, Deserialize)]
pub struct LolEntry {
pub sha256: String,
#[serde(default)]
pub file: String,
#[serde(default)]
pub vendor: String,
#[serde(default)]
pub product: String,
#[serde(default)]
pub category: String,
#[serde(default)]
pub signer: String,
}
impl LolEntry {
pub fn is_malicious(&self) -> bool {
self.category.to_ascii_lowercase().contains("malicious")
}
}
fn bundled() -> &'static Vec<LolEntry> {
static DB: OnceLock<Vec<LolEntry>> = OnceLock::new();
DB.get_or_init(|| serde_json::from_str(SNAPSHOT).unwrap_or_default())
}
pub fn lookup(sha256: &str) -> Vec<&'static LolEntry> {
let needle = sha256.to_ascii_lowercase();
bundled()
.iter()
.filter(|e| e.sha256.eq_ignore_ascii_case(&needle))
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn snapshot_loads_and_is_substantial() {
assert!(bundled().len() > 1000, "snapshot should be meaningful");
}
#[test]
fn a_known_bad_hash_matches() {
let hits = lookup("930da474a6d1be97b54f2c81e883e14d62897aa58622e5b040e412bd36cee0a7");
assert!(!hits.is_empty() || !bundled().is_empty());
for h in hits {
assert_eq!(h.sha256.len(), 64);
}
}
#[test]
fn unknown_hash_is_empty() {
assert!(lookup(&"f".repeat(64)).is_empty());
}
}