use std::collections::HashMap;
pub use oxideav_container::ReadSeek;
use oxideav_core::{Error, Result};
mod buffered;
mod file;
mod uri;
pub use buffered::BufferedSource;
pub use file::open_file;
pub type OpenSourceFn = fn(uri: &str) -> Result<Box<dyn ReadSeek>>;
pub struct SourceRegistry {
schemes: HashMap<String, OpenSourceFn>,
}
impl SourceRegistry {
pub fn new() -> Self {
Self {
schemes: HashMap::new(),
}
}
pub fn with_defaults() -> Self {
let mut r = Self::new();
r.register("file", open_file);
r
}
pub fn register(&mut self, scheme: &str, opener: OpenSourceFn) {
self.schemes.insert(scheme.to_ascii_lowercase(), opener);
}
pub fn open(&self, uri_str: &str) -> Result<Box<dyn ReadSeek>> {
let (scheme, _) = uri::split(uri_str);
let scheme = scheme.to_ascii_lowercase();
if let Some(opener) = self.schemes.get(&scheme) {
return opener(uri_str);
}
if let Some(opener) = self.schemes.get("file") {
return opener(uri_str);
}
Err(Error::Unsupported(format!(
"no source driver for scheme '{scheme}' (URI: {uri_str})"
)))
}
pub fn schemes(&self) -> impl Iterator<Item = &str> {
self.schemes.keys().map(|s| s.as_str())
}
}
impl Default for SourceRegistry {
fn default() -> Self {
Self::with_defaults()
}
}