Skip to main content

open_kioku_storage/
lib.rs

1use open_kioku_core::{
2    AnalysisFact, CodeChunk, EvidenceSourceType, File, FileId, GraphEdge, GraphNode, ImpactReport,
3    Import, IndexManifest, SearchResult, Symbol, SymbolId, SymbolOccurrence, TestTarget,
4};
5use open_kioku_errors::Result;
6use std::path::Path;
7
8pub trait MetadataStore: Send + Sync {
9    fn initialize(&self) -> Result<()>;
10    fn put_manifest(&self, manifest: &IndexManifest) -> Result<()>;
11    fn manifest(&self) -> Result<Option<IndexManifest>>;
12    fn replace_index(&self, data: IndexData<'_>) -> Result<()>;
13    fn list_files(&self, limit: usize, offset: usize) -> Result<Vec<File>>;
14    fn get_file_by_path(&self, path: &Path) -> Result<Option<File>>;
15    fn list_symbols(&self, query: Option<&str>, limit: usize, offset: usize)
16        -> Result<Vec<Symbol>>;
17    fn symbol_by_id(&self, id: &SymbolId) -> Result<Option<Symbol>>;
18    fn chunks_for_file(&self, file_id: &FileId) -> Result<Vec<CodeChunk>>;
19    fn all_chunks(&self) -> Result<Vec<CodeChunk>>;
20    fn tests(&self) -> Result<Vec<TestTarget>>;
21    fn imports(&self) -> Result<Vec<Import>>;
22    fn analysis_facts(
23        &self,
24        _source_type: Option<EvidenceSourceType>,
25        _limit: usize,
26    ) -> Result<Vec<AnalysisFact>> {
27        Ok(Vec::new())
28    }
29    fn references_for_symbol(&self, id: &SymbolId, limit: usize) -> Result<Vec<SymbolOccurrence>>;
30    fn occurrences_for_file(&self, file_id: &FileId) -> Result<Vec<SymbolOccurrence>>;
31    fn symbols_for_file(&self, _file_id: &FileId) -> Result<Vec<Symbol>> {
32        Ok(Vec::new())
33    }
34    fn find_chunks_containing(&self, query: &str, limit: usize) -> Result<Vec<CodeChunk>> {
35        let chunks = self.all_chunks()?;
36        let mut results = Vec::new();
37        for chunk in chunks {
38            if chunk.text.contains(query) {
39                results.push(chunk);
40                if results.len() >= limit {
41                    break;
42                }
43            }
44        }
45        Ok(results)
46    }
47    fn find_files_by_path_pattern(&self, pattern: &str) -> Result<Vec<File>> {
48        let files = self.list_files(usize::MAX, 0)?;
49        let lower_pattern = pattern.to_ascii_lowercase();
50        Ok(files
51            .into_iter()
52            .filter(|f| {
53                f.path
54                    .to_string_lossy()
55                    .to_ascii_lowercase()
56                    .contains(&lower_pattern)
57            })
58            .collect())
59    }
60    fn tests_for_files(&self, file_ids: &[FileId]) -> Result<Vec<TestTarget>> {
61        let tests = self.tests()?;
62        let set = file_ids.iter().collect::<std::collections::HashSet<_>>();
63        Ok(tests
64            .into_iter()
65            .filter(|t| set.contains(&t.file_id))
66            .collect())
67    }
68}
69
70pub struct IndexData<'a> {
71    pub manifest: &'a IndexManifest,
72    pub files: &'a [File],
73    pub symbols: &'a [Symbol],
74    pub chunks: &'a [CodeChunk],
75    pub tests: &'a [TestTarget],
76    pub imports: &'a [Import],
77    pub occurrences: &'a [SymbolOccurrence],
78    pub analysis_facts: &'a [AnalysisFact],
79}
80
81pub trait GraphStore: Send + Sync {
82    fn replace_graph(&self, nodes: &[GraphNode], edges: &[GraphEdge]) -> Result<()>;
83    fn neighbors(&self, node: &str, limit: usize) -> Result<(Vec<GraphNode>, Vec<GraphEdge>)>;
84    fn shortest_path(&self, from: &str, to: &str, max_depth: usize) -> Result<Vec<GraphEdge>>;
85}
86
87pub trait SearchIndex: Send + Sync {
88    fn rebuild(&mut self, chunks: &[CodeChunk], files: &[File], symbols: &[Symbol]) -> Result<()>;
89    fn search(&self, query: &str, limit: usize) -> Result<Vec<SearchResult>>;
90}
91
92pub trait ImpactStore: Send + Sync {
93    fn impact_for_file(&self, path: &Path) -> Result<ImpactReport>;
94}
95
96/// Combined store trait for types that implement both metadata and graph storage.
97pub trait OkStore: MetadataStore + GraphStore {}
98impl<T: MetadataStore + GraphStore> OkStore for T {}