Skip to main content

solti_model/domain/
flag.rs

1//! # Boolean flag
2//!
3//! [`Flag`] provides named constructors for a serialized boolean value.
4
5use serde::{Deserialize, Serialize};
6
7/// Boolean flag with explicit enable/disable constructors.
8///
9/// ```rust
10/// use solti_model::Flag;
11///
12/// let f = Flag::enabled();
13/// assert!(f.is_enabled());
14///
15/// let f: Flag = false.into();
16/// assert!(f.is_disabled());
17///
18/// let b: bool = f.into();
19/// assert!(!b);
20/// ```
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
22#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
23#[serde(transparent)]
24pub struct Flag(bool);
25
26impl Flag {
27    /// Creates an enabled flag.
28    ///
29    /// ## Example
30    ///
31    /// ```
32    /// use solti_model::Flag;
33    ///
34    /// assert!(Flag::enabled().is_enabled());
35    /// ```
36    #[inline]
37    pub const fn enabled() -> Self {
38        Self(true)
39    }
40
41    /// Creates a disabled flag.
42    ///
43    /// ## Example
44    ///
45    /// ```
46    /// use solti_model::Flag;
47    ///
48    /// assert!(Flag::disabled().is_disabled());
49    /// ```
50    #[inline]
51    pub const fn disabled() -> Self {
52        Self(false)
53    }
54
55    /// Returns whether the flag is enabled.
56    #[inline]
57    pub const fn is_enabled(&self) -> bool {
58        self.0
59    }
60
61    /// Returns whether the flag is disabled.
62    #[inline]
63    pub const fn is_disabled(&self) -> bool {
64        !self.0
65    }
66
67    /// Returns the raw boolean value.
68    #[inline]
69    pub const fn value(&self) -> bool {
70        self.0
71    }
72}
73
74impl Default for Flag {
75    #[inline]
76    fn default() -> Self {
77        Self::enabled()
78    }
79}
80
81impl From<bool> for Flag {
82    #[inline]
83    fn from(b: bool) -> Self {
84        Self(b)
85    }
86}
87
88impl From<Flag> for bool {
89    #[inline]
90    fn from(f: Flag) -> Self {
91        f.0
92    }
93}
94
95#[cfg(test)]
96mod tests {
97    use super::Flag;
98
99    #[test]
100    fn constructors_default_and_bool_conversions_are_consistent() {
101        for (flag, expected) in [
102            (Flag::default(), true),
103            (Flag::enabled(), true),
104            (Flag::disabled(), false),
105            (Flag::from(true), true),
106            (Flag::from(false), false),
107        ] {
108            assert_eq!(flag.value(), expected);
109            assert_eq!(flag.is_enabled(), expected);
110            assert_eq!(flag.is_disabled(), !expected);
111            assert_eq!(bool::from(flag), expected);
112        }
113    }
114
115    #[test]
116    fn serde_is_transparent() {
117        for (flag, json) in [(Flag::enabled(), "true"), (Flag::disabled(), "false")] {
118            assert_eq!(serde_json::to_string(&flag).unwrap(), json);
119            assert_eq!(serde_json::from_str::<Flag>(json).unwrap(), flag);
120        }
121    }
122}