use crate::Value;
use cfg_if::cfg_if;
use std::marker::PhantomData;
#[cfg_attr(feature = "async", maybe_impl::traits(Send, Sync))]
pub trait ConfigureOptions<T> {
fn configure(&self, name: Option<&str>, options: &mut T);
}
#[cfg_attr(feature = "async", maybe_impl::traits(Send, Sync))]
pub trait PostConfigureOptions<T> {
fn post_configure(&self, name: Option<&str>, options: &mut T);
}
macro_rules! config_impl {
(($($bounds:tt)+)) => {
#[inline]
pub fn configure<T, F>(action: F) -> impl ConfigureOptions<T>
where
T: Value,
F: Fn(Option<&str>, &mut T) + $($bounds)+,
{
_ConfigureOptions {
action,
_marker: PhantomData,
}
}
#[inline]
pub fn post_configure<T, F>(action: F) -> impl PostConfigureOptions<T>
where
T: Value,
F: Fn(Option<&str>, &mut T) + $($bounds)+,
{
_ConfigureOptions {
action,
_marker: PhantomData,
}
}
struct _ConfigureOptions<TOptions, TAction> {
action: TAction,
_marker: PhantomData<TOptions>,
}
impl<TOptions, TAction> ConfigureOptions<TOptions> for _ConfigureOptions<TOptions, TAction>
where
TOptions: Value,
TAction: Fn(Option<&str>, &mut TOptions) + $($bounds)+,
{
#[inline]
fn configure(&self, name: Option<&str>, options: &mut TOptions) {
(self.action)(name, options)
}
}
impl<TOptions, TAction> PostConfigureOptions<TOptions>
for _ConfigureOptions<TOptions, TAction>
where
TOptions: Value,
TAction: Fn(Option<&str>, &mut TOptions) + $($bounds)+,
{
#[inline]
fn post_configure(&self, name: Option<&str>, options: &mut TOptions) {
(self.action)(name, options)
}
}
};
}
cfg_if! {
if #[cfg(feature = "async")] {
config_impl!((Send + Sync + 'static));
} else {
config_impl!(('static));
}
}