secfinding 0.3.0

Universal security finding types for vulnerability scanners.
Documentation
use secfinding::{Finding, FindingFilter, Severity};
use std::sync::{Arc, Barrier};
use std::thread;

#[test]
fn test_concurrent_filter_reads() {
    let filter = Arc::new(FindingFilter {
        min_severity: Some(Severity::High),
        exclude_scanners: vec!["noisy-scanner".to_string()],
        include_tags: vec!["critical-tag".to_string()],
    });

    let finding = Arc::new(
        Finding::builder("good-scanner", "target", Severity::Critical)
            .title("Title")
            .tag("critical-tag")
            .build()
            .unwrap(),
    );

    let num_threads = 100;
    let barrier = Arc::new(Barrier::new(num_threads));
    let mut handles = vec![];

    for _ in 0..num_threads {
        let barrier_clone = Arc::clone(&barrier);
        let filter_clone = Arc::clone(&filter);
        let finding_clone = Arc::clone(&finding);

        handles.push(thread::spawn(move || {
            barrier_clone.wait(); // Force threads to start at the same time
            let slice = std::slice::from_ref(&*finding_clone);
            let filtered = secfinding::filter(slice, &filter_clone);
            assert_eq!(filtered.len(), 1);
            assert_eq!(filtered[0].scanner, "good-scanner");
        }));
    }

    for handle in handles {
        handle.join().unwrap();
    }
}