1use crate::Value;
2use cfg_if::cfg_if;
3use std::marker::PhantomData;
4
5#[cfg_attr(feature = "async", maybe_impl::traits(Send, Sync))]
11pub trait ConfigureOptions<T> {
12 fn configure(&self, name: Option<&str>, options: &mut T);
19}
20
21#[cfg_attr(feature = "async", maybe_impl::traits(Send, Sync))]
27pub trait PostConfigureOptions<T> {
28 fn post_configure(&self, name: Option<&str>, options: &mut T);
35}
36
37macro_rules! config_impl {
38 (($($bounds:tt)+)) => {
39 #[inline]
45 pub fn configure<T, F>(action: F) -> impl ConfigureOptions<T>
46 where
47 T: Value,
48 F: Fn(Option<&str>, &mut T) + $($bounds)+,
49 {
50 _ConfigureOptions {
51 action,
52 _marker: PhantomData,
53 }
54 }
55
56 #[inline]
62 pub fn post_configure<T, F>(action: F) -> impl PostConfigureOptions<T>
63 where
64 T: Value,
65 F: Fn(Option<&str>, &mut T) + $($bounds)+,
66 {
67 _ConfigureOptions {
68 action,
69 _marker: PhantomData,
70 }
71 }
72
73 struct _ConfigureOptions<TOptions, TAction> {
74 action: TAction,
75 _marker: PhantomData<TOptions>,
76 }
77
78 impl<TOptions, TAction> ConfigureOptions<TOptions> for _ConfigureOptions<TOptions, TAction>
79 where
80 TOptions: Value,
81 TAction: Fn(Option<&str>, &mut TOptions) + $($bounds)+,
82 {
83 #[inline]
84 fn configure(&self, name: Option<&str>, options: &mut TOptions) {
85 (self.action)(name, options)
86 }
87 }
88
89 impl<TOptions, TAction> PostConfigureOptions<TOptions>
90 for _ConfigureOptions<TOptions, TAction>
91 where
92 TOptions: Value,
93 TAction: Fn(Option<&str>, &mut TOptions) + $($bounds)+,
94 {
95 #[inline]
96
97 fn post_configure(&self, name: Option<&str>, options: &mut TOptions) {
98 (self.action)(name, options)
99 }
100 }
101 };
102}
103
104cfg_if! {
105 if #[cfg(feature = "async")] {
106 config_impl!((Send + Sync + 'static));
107 } else {
108 config_impl!(('static));
109 }
110}