use super::state::Contagion;
use super::topology::PropagationEdge;
use super::types::{ContagionContent, NodeId};
use async_trait::async_trait;
#[async_trait]
pub trait ContagionHook: Send + Sync {
async fn on_contagion_spread(
&self,
_contagion: &Contagion,
_from_node: &NodeId,
_to_node: &NodeId,
) {
}
async fn mutate_custom_content(
&self,
_content: &ContagionContent,
_noise_level: f32,
) -> Option<ContagionContent> {
None
}
async fn modify_transmission_rate(
&self,
base_rate: f32,
_edge: &PropagationEdge,
_contagion: &Contagion,
) -> f32 {
base_rate
}
}
pub struct DefaultContagionHook;
#[async_trait]
impl ContagionHook for DefaultContagionHook {}
#[cfg(test)]
mod tests {
use super::*;
use crate::plugin::contagion::types::DiseaseLevel;
#[tokio::test]
async fn test_default_hook_no_spread_event() {
let hook = DefaultContagionHook;
let contagion = Contagion::new(
"c1",
ContagionContent::Disease {
severity: DiseaseLevel::Moderate,
location: "london".to_string(),
},
"london",
0,
);
hook.on_contagion_spread(&contagion, &"london".to_string(), &"paris".to_string())
.await;
}
#[tokio::test]
async fn test_default_hook_no_custom_mutation() {
let hook = DefaultContagionHook;
let content = ContagionContent::Custom {
key: "test".to_string(),
data: serde_json::json!({"value": 42}),
};
let result = hook.mutate_custom_content(&content, 0.5).await;
assert!(result.is_none());
}
#[tokio::test]
async fn test_default_hook_no_rate_modification() {
let hook = DefaultContagionHook;
let edge = PropagationEdge::new("e1", "a", "b", 0.8);
let contagion = Contagion::new(
"c1",
ContagionContent::Disease {
severity: DiseaseLevel::Moderate,
location: "london".to_string(),
},
"london",
0,
);
let modified = hook.modify_transmission_rate(0.5, &edge, &contagion).await;
assert_eq!(modified, 0.5);
}
#[tokio::test]
async fn test_custom_hook_implementation() {
struct TestHook {
spread_multiplier: f32,
}
#[async_trait]
impl ContagionHook for TestHook {
async fn modify_transmission_rate(
&self,
base_rate: f32,
_edge: &PropagationEdge,
_contagion: &Contagion,
) -> f32 {
base_rate * self.spread_multiplier
}
}
let hook = TestHook {
spread_multiplier: 2.0,
};
let edge = PropagationEdge::new("e1", "a", "b", 0.8);
let contagion = Contagion::new(
"c1",
ContagionContent::Disease {
severity: DiseaseLevel::Moderate,
location: "london".to_string(),
},
"london",
0,
);
let modified = hook.modify_transmission_rate(0.5, &edge, &contagion).await;
assert_eq!(modified, 1.0);
}
}