use std::fmt;
use std::path::Path;
use std::time::Instant;
use warmy::{Load, Storage};
pub trait TyDesc {
const TY_DESC: &'static str;
}
pub fn load_with<T, A, E, F>(
path: &Path,
loader: F
) -> Result<A, E>
where F: FnOnce() -> Result<A, E>,
T: TyDesc {
info!("loading {} {}", T::TY_DESC, path.display());
let start_time = Instant::now();
let r = loader();
let t = start_time.elapsed();
let ns = t.as_secs() as f64 * 1e9 + t.subsec_nanos() as f64;
let (pretty_time, suffix) = load_time(ns);
if let Ok(_) = r {
info!("loaded {} {}: {:.3}{}", T::TY_DESC, path.display(), pretty_time, suffix);
} else {
err!("fail to load {} {}: {:.3}{}", T::TY_DESC, path.display(), pretty_time, suffix);
}
r
}
pub fn reload_passthrough<C, T>(
_: &T,
key: T::Key,
storage: &mut Storage<C>,
ctx: &mut C
) -> Result<T, T::Error>
where T: Load<C>,
T::Key: Clone + fmt::Debug {
let r = T::load(key.clone(), storage, ctx);
if let Err(ref e) = r {
err!("cannot reload {:?}: {:#?}", key, e);
}
r.map(|x| x.res)
}
fn load_time<'a>(ns: f64) -> (f64, &'a str) {
if ns >= 1e9 {
(ns * 1e-9, "s")
} else if ns >= 1e6 {
(ns * 1e-6, "ms")
} else if ns >= 1e3 {
(ns * 1e-3, "μs")
} else {
(ns, "ns")
}
}
#[macro_export]
macro_rules! impl_reload_passthrough {
($ctx_ty:ty) => {
fn reload(&self, key: Self::Key, storage: &mut $crate::sys::res::Storage<$ctx_ty>, ctx: &mut $ctx_ty) -> Result<Self, Self::Error> {
$crate::sys::res::helpers::reload_passthrough(self, key, storage, ctx)
}
}
}