llmcc_core/
file.rs

1use std::hash::{DefaultHasher, Hash, Hasher};
2
3#[derive(Debug, Clone, Default)]
4pub struct FileId {
5    pub path: Option<String>,
6    pub content: Option<Vec<u8>>,
7    pub content_hash: u64,
8}
9
10impl FileId {
11    pub fn new_path(path: String) -> std::io::Result<Self> {
12        let content = std::fs::read(&path)?;
13
14        let mut hasher = DefaultHasher::new();
15        content.hash(&mut hasher);
16        let content_hash = hasher.finish();
17
18        Ok(FileId {
19            path: Some(path),
20            content: Some(content),
21            content_hash,
22        })
23    }
24
25    pub fn new_content(content: Vec<u8>) -> Self {
26        let mut hasher = DefaultHasher::new();
27        hasher.write(&content);
28        let content_hash = hasher.finish();
29
30        FileId {
31            path: None,
32            content: Some(content),
33            content_hash,
34        }
35    }
36
37    pub fn get_text(&self, start_byte: usize, end_byte: usize) -> Option<String> {
38        let content_bytes = self.content.as_ref()?;
39
40        if start_byte > end_byte
41            || start_byte > content_bytes.len()
42            || end_byte > content_bytes.len()
43        {
44            return None;
45        }
46
47        let slice = &content_bytes[start_byte..end_byte];
48        Some(String::from_utf8_lossy(slice).into_owned())
49    }
50
51    pub fn get_full_text(&self) -> Option<String> {
52        let content_bytes = self.content.as_ref()?;
53        Some(String::from_utf8_lossy(content_bytes).into_owned())
54    }
55}
56
57#[derive(Debug, Clone, Default)]
58pub struct File {
59    // TODO: add cache and all other stuff
60    pub file: FileId,
61}
62
63impl File {
64    pub fn new_source(source: Vec<u8>) -> Self {
65        File {
66            file: FileId::new_content(source),
67        }
68    }
69
70    pub fn new_file(file: String) -> std::io::Result<Self> {
71        Ok(File {
72            file: FileId::new_path(file)?,
73        })
74    }
75
76    pub fn content(&self) -> Vec<u8> {
77        self.file.content.as_ref().unwrap().to_vec()
78    }
79
80    pub fn get_text(&self, start: usize, end: usize) -> String {
81        self.file.get_text(start, end).unwrap()
82    }
83
84    pub fn opt_get_text(&self, start: usize, end: usize) -> Option<String> {
85        self.file.get_text(start, end)
86    }
87
88    pub fn path(&self) -> Option<&str> {
89        self.file.path.as_deref()
90    }
91}