use crate::graph::types::GraphFact;
use crate::types::MessageId;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum RecallView {
#[default]
Head,
ZoomIn,
ZoomOut,
}
#[derive(Debug, Clone)]
pub struct RecalledFact {
pub fact: GraphFact,
pub activation_score: Option<f32>,
pub provenance_message_id: Option<MessageId>,
pub provenance_snippet: Option<String>,
pub neighbors: Vec<GraphFact>,
}
impl RecalledFact {
#[must_use]
pub fn from_graph_fact(fact: GraphFact) -> Self {
Self {
fact,
activation_score: None,
provenance_message_id: None,
provenance_snippet: None,
neighbors: Vec::new(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::graph::types::{EdgeType, GraphFact};
use crate::types::MessageId;
fn make_fact() -> GraphFact {
GraphFact {
entity_name: "Rust".to_string(),
relation: "uses".to_string(),
target_name: "LLVM".to_string(),
fact: "Rust uses LLVM".to_string(),
entity_match_score: 0.9,
hop_distance: 0,
confidence: 0.95,
valid_from: None,
edge_type: EdgeType::Semantic,
retrieval_count: 0,
edge_id: None,
}
}
#[test]
fn from_graph_fact_no_enrichment() {
let rf = RecalledFact::from_graph_fact(make_fact());
assert!(rf.activation_score.is_none());
assert!(rf.provenance_message_id.is_none());
assert!(rf.provenance_snippet.is_none());
assert!(rf.neighbors.is_empty());
}
#[test]
fn recall_view_default_is_head() {
assert_eq!(RecallView::default(), RecallView::Head);
}
fn head_fact() -> RecalledFact {
RecalledFact::from_graph_fact(GraphFact {
entity_name: "Rust".to_string(),
relation: "uses".to_string(),
target_name: "LLVM".to_string(),
fact: "Rust uses LLVM for code generation".to_string(),
entity_match_score: 0.9,
hop_distance: 0,
confidence: 0.95,
valid_from: Some("2026-01-01".to_string()),
edge_type: EdgeType::Semantic,
retrieval_count: 1,
edge_id: Some(10),
})
}
#[test]
fn snapshot_head_no_enrichment() {
let rf = head_fact();
insta::assert_debug_snapshot!("head_view", rf);
}
#[test]
fn snapshot_zoom_in_with_provenance() {
let mut rf = head_fact();
rf.provenance_message_id = Some(MessageId(42));
rf.provenance_snippet = Some("The Rust compiler uses LLVM as its backend".to_string());
insta::assert_debug_snapshot!("zoom_in_view", rf);
}
#[test]
fn snapshot_zoom_out_with_neighbors() {
let mut rf = head_fact();
rf.neighbors.push(GraphFact {
entity_name: "LLVM".to_string(),
relation: "supports".to_string(),
target_name: "WebAssembly".to_string(),
fact: "LLVM supports WebAssembly output".to_string(),
entity_match_score: 0.5,
hop_distance: 1,
confidence: 0.8,
valid_from: None,
edge_type: EdgeType::Semantic,
retrieval_count: 0,
edge_id: Some(11),
});
insta::assert_debug_snapshot!("zoom_out_view", rf);
}
#[test]
fn snapshot_sa_fact_with_activation_score() {
let rf = RecalledFact {
fact: GraphFact {
entity_name: String::new(),
relation: "uses".to_string(),
target_name: String::new(),
fact: "Rust uses LLVM for compilation".to_string(),
entity_match_score: 0.82,
hop_distance: 0,
confidence: 0.9,
valid_from: Some("2026-01-01".to_string()),
edge_type: EdgeType::Semantic,
retrieval_count: 0,
edge_id: Some(55),
},
activation_score: Some(0.82),
provenance_message_id: None,
provenance_snippet: None,
neighbors: Vec::new(),
};
insta::assert_debug_snapshot!("sa_head_view", rf);
}
}