Skip to main content

winx_code_agent/utils/
file_cache.rs

1#![allow(clippy::unwrap_used)]
2use crate::errors::Result;
3use std::collections::HashMap;
4use std::path::{Path, PathBuf};
5use std::sync::{Arc, Mutex, OnceLock};
6
7/// Minimal file cache for MCP core tools
8#[derive(Debug, Default)]
9pub struct FileCacheInner {
10    pub read_ranges: HashMap<PathBuf, Vec<(usize, usize)>>,
11    pub file_hashes: HashMap<PathBuf, String>,
12}
13
14#[derive(Debug, Clone, Default)]
15pub struct FileCache {
16    inner: Arc<Mutex<FileCacheInner>>,
17}
18
19impl FileCache {
20    pub fn global() -> &'static Self {
21        static CACHE: OnceLock<FileCache> = OnceLock::new();
22        CACHE.get_or_init(FileCache::default)
23    }
24
25    pub fn record_read_range(&self, path: &Path, start: usize, end: usize) -> Result<()> {
26        let mut inner = self.inner.lock().unwrap();
27        inner.read_ranges.entry(path.to_path_buf()).or_default().push((start, end));
28        Ok(())
29    }
30
31    pub fn get_cached_hash(&self, path: &Path) -> Option<String> {
32        let inner = self.inner.lock().unwrap();
33        inner.file_hashes.get(path).cloned()
34    }
35
36    pub fn get_unread_ranges(&self, _path: &Path) -> Vec<(usize, usize)> {
37        // Simple placeholder for now
38        vec![]
39    }
40
41    pub fn record_file_edit(&self, path: &Path) -> Result<()> {
42        let mut inner = self.inner.lock().unwrap();
43        inner.file_hashes.remove(path);
44        Ok(())
45    }
46
47    pub fn record_file_write(&self, path: &Path) -> Result<()> {
48        let mut inner = self.inner.lock().unwrap();
49        inner.file_hashes.remove(path);
50        Ok(())
51    }
52}