sara_core/graph/
stats.rs

1//! Graph statistics collection.
2
3use std::collections::HashMap;
4
5use serde::Serialize;
6
7use crate::model::ItemType;
8
9use super::KnowledgeGraph;
10
11/// Statistics about a knowledge graph.
12#[derive(Debug, Default, Clone, Serialize)]
13pub struct GraphStats {
14    /// Total number of items in the graph.
15    pub item_count: usize,
16    /// Total number of relationships in the graph.
17    pub relationship_count: usize,
18    /// Count of items by their type.
19    pub items_by_type: HashMap<ItemType, usize>,
20}
21
22impl GraphStats {
23    /// Collects statistics from a knowledge graph.
24    pub fn from_graph(graph: &KnowledgeGraph) -> Self {
25        Self {
26            item_count: graph.item_count(),
27            relationship_count: graph.relationship_count(),
28            items_by_type: graph.count_by_type(),
29        }
30    }
31}
32
33#[cfg(test)]
34mod tests {
35    use super::*;
36    use crate::model::{Item, ItemBuilder, ItemId, SourceLocation};
37    use std::path::PathBuf;
38
39    fn create_test_item(id: &str, item_type: ItemType) -> Item {
40        let source = SourceLocation::new(PathBuf::from("/repo"), format!("{}.md", id));
41        let mut builder = ItemBuilder::new()
42            .id(ItemId::new_unchecked(id))
43            .item_type(item_type)
44            .name(format!("Test {}", id))
45            .source(source);
46
47        if item_type.requires_specification() {
48            builder = builder.specification("Test specification");
49        }
50
51        builder.build().unwrap()
52    }
53
54    #[test]
55    fn test_graph_stats() {
56        let mut graph = KnowledgeGraph::new(false);
57        graph.add_item(create_test_item("SOL-001", ItemType::Solution));
58        graph.add_item(create_test_item("UC-001", ItemType::UseCase));
59        graph.add_item(create_test_item("UC-002", ItemType::UseCase));
60
61        let stats = GraphStats::from_graph(&graph);
62
63        assert_eq!(stats.item_count, 3);
64        assert_eq!(stats.relationship_count, 0);
65        assert_eq!(stats.items_by_type.get(&ItemType::Solution), Some(&1));
66        assert_eq!(stats.items_by_type.get(&ItemType::UseCase), Some(&2));
67    }
68}