Skip to main content

options/
configure.rs

1use crate::Value;
2use cfg_if::cfg_if;
3use std::marker::PhantomData;
4
5/// Defines the behavior of something that configures [`Options`](crate::Options).
6///
7/// # Remarks
8///
9/// These are all run first
10#[cfg_attr(feature = "async", maybe_impl::traits(Send, Sync))]
11pub trait ConfigureOptions<T> {
12    /// Configures the corresponding options.
13    ///
14    /// # Arguments
15    ///
16    /// * `name` - The optional name of the options to configure
17    /// * `options` - The options to configure
18    fn configure(&self, name: Option<&str>, options: &mut T);
19}
20
21/// Defines the behavior of something that configures [`Options`](crate::Options).
22///
23/// # Remarks
24///
25/// These are all run last
26#[cfg_attr(feature = "async", maybe_impl::traits(Send, Sync))]
27pub trait PostConfigureOptions<T> {
28    /// Configures the corresponding options.
29    ///
30    /// # Arguments
31    ///
32    /// * `name` - The optional name of the options to configure
33    /// * `options` - The options to configure
34    fn post_configure(&self, name: Option<&str>, options: &mut T);
35}
36
37macro_rules! config_impl {
38    (($($bounds:tt)+)) => {
39        /// Creates and returns [options configuration](ConfigureOptions) for the specified action.
40        ///
41        /// # Arguments
42        ///
43        /// * `action` - The configuration action
44        #[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        /// Creates and returns [options post-configuration](PostConfigureOptions) for the specified action.
57        ///
58        /// # Arguments
59        ///
60        /// * `action` - The post configuration action
61        #[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}