use std::path::PathBuf; use std::sync::Arc; pub struct SourceFile { pub id: usize, pub path: PathBuf, pub source: Arc, } pub struct FileManager { files: Vec, } impl FileManager { pub fn new() -> Self { Self { files: Vec::new() } } pub fn add(&mut self, path: PathBuf, source: String) -> usize { let id = self.files.len(); self.files.push(SourceFile { id, path, source: Arc::from(source), }); id } pub fn get_file(&self, id: usize) -> Option<&SourceFile> { self.files.get(id) } pub fn get_path(&self, id: usize) -> Option { self.files.get(id).map(|f| f.path.clone()) } pub fn lookup_pos(&self, file_id: usize, pos: u32) -> (usize, usize) { let file = if let Some(f) = self.files.get(file_id) { f } else { return (0, 0); }; let mut line = 1; let mut col = 1; for (i, c) in file.source.char_indices() { if i as u32 == pos { break; } if c == '\n' { line += 1; col = 1; } else { col += 1; } } (line, col) } }