use std::fmt::Debug;
use crate::map::ErasedTy;
use crate::Error;
use super::AnyValue;
#[cfg(feature = "sync")]
mod __initializer {
use super::*;
pub trait InitializeValue<T: ErasedTy>: Send + Sync {
type Error: Into<Error>;
fn prepare_value(&mut self) -> Result<T, Self::Error>;
}
impl<Func, Err, T: ErasedTy> InitializeValue<T> for Func
where
Err: Into<Error>,
Func: FnMut() -> Result<T, Err> + Send + Sync,
{
type Error = Err;
fn prepare_value(&mut self) -> Result<T, Self::Error> {
(self)()
}
}
pub type InitHandler<T> = Box<dyn FnMut(&mut T) -> Result<(), Error> + Send + Sync>;
}
#[cfg(not(feature = "sync"))]
mod __initializer {
use super::*;
pub trait InitializeValue<T: ErasedTy> {
type Error: Into<Error>;
fn prepare_value(&mut self) -> Result<T, Self::Error>;
}
impl<Func, Err, T: ErasedTy> InitializeValue<T> for Func
where
Err: Into<Error>,
Func: FnMut() -> Result<T, Err>,
{
type Error = Err;
fn prepare_value(&mut self) -> Result<T, Self::Error> {
(self)()
}
}
pub type InitHandler<T> = Box<dyn FnMut(&mut T) -> Result<(), Error>>;
}
pub use __initializer::InitHandler;
pub use __initializer::InitializeValue;
pub struct ValInitializer(InitHandler<AnyValue>);
impl Debug for ValInitializer {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("ValInitializer").field(&"{...}").finish()
}
}
impl ValInitializer {
pub fn new<U: ErasedTy>(mut init: impl InitializeValue<Vec<U>> + 'static) -> Self {
Self(Box::new(move |erased_val| {
erased_val.set(init.prepare_value().map_err(Into::into)?);
Ok(())
}))
}
pub fn new_value<U: Clone + ErasedTy>(val: U) -> Self {
Self(Box::new(move |erased_val| {
erased_val.set(vec![val.clone()]);
Ok(())
}))
}
pub fn new_values<U: Clone + ErasedTy>(vals: Vec<U>) -> Self {
Self(Box::new(move |erased_val| {
erased_val.set(vals.clone());
Ok(())
}))
}
pub fn fallback() -> Self {
Self(Box::new(|_| Ok(())))
}
pub fn invoke(&mut self, arg: &mut AnyValue) -> Result<(), Error> {
(self.0)(arg)
}
pub fn values<T: ErasedTy>(&mut self) -> Result<Option<Vec<T>>, Error> {
let mut any_value = AnyValue::new();
self.invoke(&mut any_value)?;
Ok(any_value.remove())
}
}
#[cfg(not(feature = "sync"))]
impl<T: FnMut(&mut AnyValue) -> Result<(), Error> + 'static> From<T> for ValInitializer {
fn from(value: T) -> Self {
Self(Box::new(value))
}
}
#[cfg(feature = "sync")]
impl<T: FnMut(&mut AnyValue) -> Result<(), Error> + Send + Sync + 'static> From<T>
for ValInitializer
{
fn from(value: T) -> Self {
Self(Box::new(value))
}
}