entracte_lib/plugins/
eval.rs1use super::manifest::Capability;
10use super::runtime::evaluate_detector;
11
12#[derive(Debug, Clone)]
15pub struct DetectorSnapshot {
16 pub id: String,
17 pub capabilities: Vec<Capability>,
18 pub process_pattern: Option<String>,
19}
20
21pub fn any_detector_suppresses(
27 detectors: &[DetectorSnapshot],
28 load: impl Fn(&str) -> Option<Vec<u8>>,
29) -> bool {
30 detectors.iter().any(|d| match load(&d.id) {
31 Some(module) => evaluate_detector(&module, &d.capabilities, d.process_pattern.clone()),
32 None => false,
33 })
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39
40 fn suppress_if_process_module() -> Vec<u8> {
43 wat::parse_str(
44 r#"(module
45 (import "extism:host/user" "host_process_running" (func $proc (result i64)))
46 (import "extism:host/user" "host_suppress" (func $suppress))
47 (memory (export "memory") 1)
48 (func (export "detect") (result i32)
49 (if (i64.ne (call $proc) (i64.const 0)) (then (call $suppress)))
50 (i32.const 0)))"#,
51 )
52 .unwrap()
53 }
54
55 fn snapshot(id: &str, pattern: &str) -> DetectorSnapshot {
56 DetectorSnapshot {
57 id: id.to_string(),
58 capabilities: vec![Capability::DetectProcesses],
59 process_pattern: Some(pattern.to_string()),
60 }
61 }
62
63 #[test]
64 fn suppresses_when_any_detector_votes() {
65 let module = suppress_if_process_module();
66 let load = |_id: &str| Some(module.clone());
67 let detectors = vec![
69 snapshot("com.x.idle", "entracte-no-such-zzz"),
70 snapshot("com.x.focus", "entracte"),
71 ];
72 assert!(any_detector_suppresses(&detectors, load));
73 }
74
75 #[test]
76 fn no_suppression_when_none_vote() {
77 let module = suppress_if_process_module();
78 let detectors = vec![snapshot("com.x.idle", "entracte-no-such-zzz")];
79 assert!(!any_detector_suppresses(&detectors, |_| Some(
80 module.clone()
81 )));
82 }
83
84 #[test]
85 fn a_missing_module_is_skipped() {
86 let detectors = vec![snapshot("com.x.gone", "entracte")];
87 assert!(!any_detector_suppresses(&detectors, |_| None));
89 }
90
91 #[test]
92 fn empty_set_does_not_suppress() {
93 assert!(!any_detector_suppresses(&[], |_| Some(vec![1, 2, 3])));
94 }
95}