use std::{ops::Deref, path::PathBuf};
use rustc_hash::FxHashMap;
pub trait FileProvider {
fn read_file(&self, name: &str) -> Option<Box<str>>;
}
impl<T, U> FileProvider for T
where
T: Deref<Target = U>,
U: FileProvider,
{
fn read_file(&self, name: &str) -> Option<Box<str>> {
self.deref().read_file(name)
}
}
#[derive(Debug, Default)]
pub struct FsFileProvider {
pub root: PathBuf,
}
impl FsFileProvider {
pub fn new(root: PathBuf) -> Self {
FsFileProvider { root }
}
}
impl FileProvider for FsFileProvider {
fn read_file(&self, name: &str) -> Option<Box<str>> {
let path = self.root.join(PathBuf::from(name));
std::fs::read_to_string(path).ok().map(Into::into)
}
}
#[derive(Debug, Default)]
pub struct MemoryFileProvider {
files: FxHashMap<Box<str>, Box<str>>,
}
impl MemoryFileProvider {
pub fn add_file(&mut self, path: Box<str>, content: Box<str>) {
self.files.insert(path, content);
}
}
impl FileProvider for MemoryFileProvider {
fn read_file(&self, name: &str) -> Option<Box<str>> {
self.files.get(name).cloned()
}
}