use crate::context::ResourceContext;
use async_trait::async_trait;
use super::types::*;
#[async_trait]
pub trait ResearchHook: Send + Sync {
async fn on_research_queued(
&self,
_project: &ResearchProject,
_resources: &mut ResourceContext,
) {
}
async fn on_research_started(
&self,
_project: &ResearchProject,
_resources: &mut ResourceContext,
) {
}
async fn calculate_research_cost(
&self,
project: &ResearchProject,
_resources: &ResourceContext,
) -> Result<i64, String> {
Ok(project.cost)
}
async fn calculate_progress(
&self,
_project: &ResearchProject,
base_progress: f32,
_resources: &ResourceContext,
) -> f32 {
base_progress
}
async fn on_research_completed(
&self,
_project: &ResearchProject,
_result: &ResearchResult,
_resources: &mut ResourceContext,
) {
}
async fn on_research_failed(
&self,
_project: &ResearchProject,
_resources: &mut ResourceContext,
) {
}
async fn validate_prerequisites(
&self,
_project: &ResearchProject,
_resources: &ResourceContext,
) -> Result<(), String> {
Ok(())
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct DefaultResearchHook;
#[async_trait]
impl ResearchHook for DefaultResearchHook {
}
#[cfg(test)]
mod tests {
use super::*;
use crate::context::ResourceContext;
#[tokio::test]
async fn test_default_hook_does_nothing() {
let hook = DefaultResearchHook;
let project = ResearchProject::new("test", "Test", "Test");
let result = ResearchResult::new(ResearchId::new("test"), true);
let mut resources = ResourceContext::new();
hook.on_research_queued(&project, &mut resources).await;
hook.on_research_started(&project, &mut resources).await;
let cost = hook.calculate_research_cost(&project, &resources).await;
assert_eq!(cost, Ok(0));
let progress = hook.calculate_progress(&project, 0.1, &resources).await;
assert_eq!(progress, 0.1);
hook.on_research_completed(&project, &result, &mut resources)
.await;
hook.on_research_failed(&project, &mut resources).await;
let validation = hook.validate_prerequisites(&project, &resources).await;
assert!(validation.is_ok());
}
#[tokio::test]
async fn test_default_hook_returns_project_cost() {
let hook = DefaultResearchHook;
let project = ResearchProject::new("test", "Test", "Test").with_cost(5000);
let resources = ResourceContext::new();
let cost = hook.calculate_research_cost(&project, &resources).await;
assert_eq!(cost, Ok(5000));
}
}