Skip to main content

configbuilder_pattern_loader/
feature_state.rs

1/// Whether an optional TOML section is present and active.
2///
3/// `load_optional_section` returns `Enabled(T)` when the key exists in any
4/// config file and `Disabled` when it is absent from all of them.
5pub enum FeatureState<T> {
6    /// The section key is present in TOML and deserialized successfully into `T`.
7    Enabled(T),
8    /// The section key is absent from every config file -- the feature is off.
9    Disabled,
10}
11
12impl<T: std::fmt::Debug> std::fmt::Debug for FeatureState<T> {
13    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
14        match self {
15            Self::Enabled(v) => f.debug_tuple("Enabled").field(v).finish(),
16            Self::Disabled => write!(f, "Disabled"),
17        }
18    }
19}
20
21impl<T: Clone> Clone for FeatureState<T> {
22    fn clone(&self) -> Self {
23        match self {
24            Self::Enabled(v) => Self::Enabled(v.clone()),
25            Self::Disabled => Self::Disabled,
26        }
27    }
28}
29
30impl<T: PartialEq> PartialEq for FeatureState<T> {
31    fn eq(&self, other: &Self) -> bool {
32        match (self, other) {
33            (Self::Enabled(a), Self::Enabled(b)) => a == b,
34            (Self::Disabled, Self::Disabled) => true,
35            _ => false,
36        }
37    }
38}
39
40impl<T> From<Option<T>> for FeatureState<T> {
41    fn from(opt: Option<T>) -> Self {
42        match opt {
43            Some(v) => Self::Enabled(v),
44            None => Self::Disabled,
45        }
46    }
47}
48
49impl<T> From<FeatureState<T>> for Option<T> {
50    fn from(state: FeatureState<T>) -> Self {
51        state.into_option()
52    }
53}
54
55impl<T> FeatureState<T> {
56    pub(crate) fn is_enabled(&self) -> bool {
57        matches!(self, Self::Enabled(_))
58    }
59
60    pub(crate) fn is_disabled(&self) -> bool {
61        matches!(self, Self::Disabled)
62    }
63
64    pub(crate) fn into_option(self) -> Option<T> {
65        match self {
66            Self::Enabled(v) => Some(v),
67            Self::Disabled => None,
68        }
69    }
70
71    pub(crate) fn as_option(&self) -> Option<&T> {
72        match self {
73            Self::Enabled(v) => Some(v),
74            Self::Disabled => None,
75        }
76    }
77
78    pub(crate) fn map<U>(self, f: impl FnOnce(T) -> U) -> FeatureState<U> {
79        match self {
80            Self::Enabled(v) => FeatureState::Enabled(f(v)),
81            Self::Disabled => FeatureState::Disabled,
82        }
83    }
84
85    pub(crate) fn and_then<U>(self, f: impl FnOnce(T) -> FeatureState<U>) -> FeatureState<U> {
86        match self {
87            Self::Enabled(v) => f(v),
88            Self::Disabled => FeatureState::Disabled,
89        }
90    }
91
92    pub(crate) fn unwrap_or(self, default: T) -> T {
93        match self {
94            Self::Enabled(v) => v,
95            Self::Disabled => default,
96        }
97    }
98
99    pub(crate) fn unwrap_or_else(self, f: impl FnOnce() -> T) -> T {
100        match self {
101            Self::Enabled(v) => v,
102            Self::Disabled => f(),
103        }
104    }
105
106    pub(crate) fn enabled_or_default(self) -> T
107    where
108        T: Default,
109    {
110        self.unwrap_or_else(T::default)
111    }
112}
113
114impl<T> crate::FeatureStateOps for FeatureState<T> {
115    type Value = T;
116
117    fn is_enabled(&self) -> bool {
118        FeatureState::is_enabled(self)
119    }
120
121    fn is_disabled(&self) -> bool {
122        FeatureState::is_disabled(self)
123    }
124
125    fn into_option(self) -> Option<Self::Value> {
126        FeatureState::into_option(self)
127    }
128
129    fn as_option(&self) -> Option<&Self::Value> {
130        FeatureState::as_option(self)
131    }
132
133    fn map<U>(self, f: impl FnOnce(Self::Value) -> U) -> FeatureState<U> {
134        FeatureState::map(self, f)
135    }
136
137    fn and_then<U>(self, f: impl FnOnce(Self::Value) -> FeatureState<U>) -> FeatureState<U> {
138        FeatureState::and_then(self, f)
139    }
140
141    fn unwrap_or(self, default: Self::Value) -> Self::Value {
142        FeatureState::unwrap_or(self, default)
143    }
144
145    fn unwrap_or_else(self, f: impl FnOnce() -> Self::Value) -> Self::Value {
146        FeatureState::unwrap_or_else(self, f)
147    }
148
149    fn enabled_or_default(self) -> Self::Value
150    where
151        Self::Value: Default,
152    {
153        FeatureState::enabled_or_default(self)
154    }
155}