use crate::load::{Answer, DirEntry, FileKind, LoadedPlugin, Loading, Question, Rejection};
use crate::path::PackagePath;
pub trait Source {
type Error: std::fmt::Display;
fn kind(&mut self, path: &PackagePath) -> Result<Option<FileKind>, Self::Error>;
fn confined(&mut self, path: &PackagePath) -> Result<bool, Self::Error>;
fn read(&mut self, path: &PackagePath) -> Result<Vec<u8>, Self::Error>;
fn list(&mut self, path: &PackagePath) -> Result<Vec<DirEntry>, Self::Error>;
}
pub fn load<S: Source>(source: &mut S) -> Result<LoadedPlugin, Rejection> {
let mut loading = Loading::start();
while let Some(question) = loading.question() {
let answer = match &question {
Question::Kind(path) => match source.kind(path) {
Ok(kind) => Answer::Kind(kind),
Err(e) => Answer::Unavailable { detail: e.to_string() },
},
Question::Confined(path) => match source.confined(path) {
Ok(confined) => Answer::Confined(confined),
Err(e) => Answer::Unavailable { detail: e.to_string() },
},
Question::Read(path) => match source.read(path) {
Ok(bytes) => Answer::Bytes(bytes),
Err(e) => Answer::Unavailable { detail: e.to_string() },
},
Question::List(path) => match source.list(path) {
Ok(entries) => Answer::Entries(entries),
Err(e) => Answer::Unavailable { detail: e.to_string() },
},
};
loading.answer(answer).expect("answer variant matches the question just asked");
}
loading.finish()
}