use async_trait::async_trait;
use crate::document::{DocumentTree, NodeId};
use super::{InterventionPoint, Pilot, PilotConfig, PilotDecision, SearchState};
#[derive(Debug, Clone, Default)]
pub struct NoopPilot {
config: PilotConfig,
}
impl NoopPilot {
pub fn new() -> Self {
Self {
config: PilotConfig::algorithm_only(),
}
}
pub fn with_config(config: PilotConfig) -> Self {
Self { config }
}
}
#[async_trait]
impl Pilot for NoopPilot {
fn name(&self) -> &str {
"noop"
}
fn should_intervene(&self, _state: &SearchState<'_>) -> bool {
false
}
async fn decide(&self, state: &SearchState<'_>) -> PilotDecision {
let decision = PilotDecision::preserve_order(state.candidates);
PilotDecision {
intervention_point: InterventionPoint::Fork,
..decision
}
}
async fn guide_start(
&self,
_tree: &DocumentTree,
_query: &str,
_start_node: NodeId,
) -> Option<PilotDecision> {
None
}
async fn guide_backtrack(&self, _state: &SearchState<'_>) -> Option<PilotDecision> {
None
}
fn config(&self) -> &PilotConfig {
&self.config
}
fn is_active(&self) -> bool {
false
}
fn reset(&self) {
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::document::NodeId;
use std::collections::HashSet;
#[test]
fn test_noop_pilot_never_intervenes() {
let pilot = NoopPilot::new();
let tree = DocumentTree::new("test", "test content");
let query = "test query";
let path: &[NodeId] = &[];
let candidates: &[NodeId] = &[];
let visited = HashSet::new();
let state = SearchState::new(&tree, query, path, candidates, &visited);
assert!(!pilot.should_intervene(&state));
}
#[tokio::test]
async fn test_noop_pilot_returns_default_decision() {
let pilot = NoopPilot::new();
let tree = DocumentTree::new("test", "test content");
let query = "test query";
let path: &[NodeId] = &[];
let candidates: &[NodeId] = &[];
let visited = HashSet::new();
let state = SearchState::new(&tree, query, path, candidates, &visited);
let decision = pilot.decide(&state).await;
assert_eq!(decision.confidence, 0.0);
assert!(!decision.has_candidates());
}
#[tokio::test]
async fn test_noop_pilot_no_start_guidance() {
let pilot = NoopPilot::new();
let tree = DocumentTree::new("test", "test content");
let guidance = pilot.guide_start(&tree, "test", tree.root()).await;
assert!(guidance.is_none());
}
#[test]
fn test_noop_pilot_not_active() {
let pilot = NoopPilot::new();
assert!(!pilot.is_active());
}
}