use futures_util::FutureExt;
use tokio::fs::File;
use tokio_util::io::ReaderStream;
use std::{
collections::HashSet,
path::{Path, PathBuf},
};
use crate::{
error::LocalInfileError,
local_infile_handler::{BoxFuture, GlobalHandler},
};
#[derive(Clone, Debug)]
pub struct WhiteListFsHandler {
white_list: HashSet<PathBuf>,
}
impl WhiteListFsHandler {
pub fn new<A, B>(white_list: B) -> WhiteListFsHandler
where
A: Into<PathBuf>,
B: IntoIterator<Item = A>,
{
let mut white_list_set = HashSet::new();
for path in white_list.into_iter() {
white_list_set.insert(Into::<PathBuf>::into(path));
}
WhiteListFsHandler {
white_list: white_list_set,
}
}
}
impl GlobalHandler for WhiteListFsHandler {
fn handle(&self, file_name: &[u8]) -> BoxFuture<'static, super::InfileData> {
let path = String::from_utf8_lossy(file_name);
let path = self
.white_list
.get(Path::new(&*path))
.cloned()
.ok_or_else(|| LocalInfileError::PathIsNotInTheWhiteList(path.into_owned()));
async move {
let file = File::open(path?).await?;
Ok(Box::pin(ReaderStream::new(file)) as super::InfileData)
}
.boxed()
}
}