use crate::{
entity::ConfigurationEntity,
loader::{Error, Loader},
};
use std::fmt::{Debug, Display, Formatter};
use url::Url;
pub type BoxedLoaderFn = Box<
dyn Fn(&Url, Option<&[String]>, bool) -> Result<Vec<(String, ConfigurationEntity)>, Error>
+ Send
+ Sync,
>;
pub struct Closure {
name: String,
loader: BoxedLoaderFn,
scheme_list: Vec<String>,
}
impl Debug for Closure {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ConfigurationLoaderFn")
.field("name", &self.name)
.field("scheme_list", &self.scheme_list)
.finish()
}
}
impl Closure {
pub fn new<S: AsRef<str>, N: AsRef<str>>(name: N, loader: BoxedLoaderFn, scheme: S) -> Self {
Self {
name: name.as_ref().to_string(),
loader,
scheme_list: [scheme.as_ref().into()].into(),
}
}
pub fn set_name<N: AsRef<str>>(&mut self, name: N) {
self.name = name.as_ref().to_string()
}
pub fn with_name<N: AsRef<str>>(mut self, name: N) -> Self {
self.set_name(name);
self
}
pub fn set_loader(&mut self, loader: BoxedLoaderFn) {
self.loader = loader
}
pub fn with_loader(mut self, loader: BoxedLoaderFn) -> Self {
self.set_loader(loader);
self
}
pub fn set_scheme_list<S: AsRef<str>>(&mut self, scheme_list: Vec<S>) {
self.scheme_list = scheme_list
.into_iter()
.map(|scheme| scheme.as_ref().to_string())
.collect();
}
pub fn with_scheme_list<S: AsRef<str>>(mut self, scheme_list: Vec<S>) -> Self {
self.set_scheme_list(scheme_list);
self
}
}
impl Display for Closure {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str(self.name.as_str())
}
}
impl Loader for Closure {
fn scheme_list(&self) -> Vec<String> {
self.scheme_list.clone()
}
fn load(
&self,
url: &Url,
maybe_whitelist: Option<&[String]>,
skip_soft_errors: bool,
) -> Result<Vec<(String, ConfigurationEntity)>, Error> {
(self.loader)(url, maybe_whitelist, skip_soft_errors)
}
}