iowo/crates/lang/src/world/files.rs

57 lines
1.4 KiB
Rust

use std::{
collections::HashMap,
io,
path::{Path, PathBuf},
};
mod loc;
pub use loc::Loc;
use rowan::ast::AstNode;
use crate::{
ast::ParseError,
lst_parser::{self, error::SyntaxError, input, output::Output},
world::{error::Error, files::source_file::SourceFile},
};
#[derive(Default)]
pub struct Files {
inner: Vec<source_file::SourceFile>,
path_to_id_map: HashMap<PathBuf, FileId>,
}
impl Files {
pub fn add_file(&mut self, path: &Path) -> Result<(FileId, Vec<Error>), OpenFileError> {
if !path.exists() {
return Err(OpenFileError::NotFound(path.to_owned()));
}
let file_id = FileId(self.inner.len());
let (source_file, errs) = match SourceFile::open(path) {
Ok((source_file, errs)) => {
let errs = errs
.into_iter()
.map(|(ptr, err)| Error::Syntax(Loc::from_ptr(ptr, file_id), err))
.collect::<Vec<_>>();
(source_file, errs)
}
Err(e) => return Err(OpenFileError::IoError(path.to_path_buf(), e)),
};
self.inner.push(source_file);
self.path_to_id_map.insert(path.to_path_buf(), file_id);
Ok((file_id, errs))
}
}
pub enum OpenFileError {
NotFound(PathBuf),
IoError(PathBuf, std::io::Error),
}
#[derive(Copy, Clone, Debug)]
pub struct FileId(usize);
mod source_file;