swc_config/types/
bool_or_data.rs1use serde::{Deserialize, Serialize};
2
3use crate::merge::Merge;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
6pub struct BoolOrDataConfig<T>(#[serde(default)] Option<BoolOr<T>>);
7
8impl<T> BoolOrDataConfig<T> {
9 pub fn from_bool(v: bool) -> Self {
10 Self(Some(BoolOr::Bool(v)))
11 }
12
13 pub fn from_obj(v: T) -> Self {
14 v.into()
15 }
16
17 pub fn as_ref(&self) -> BoolOrDataConfig<&T> {
18 match &self.0 {
19 Some(BoolOr::Data(v)) => BoolOrDataConfig::from_obj(v),
20 Some(BoolOr::Bool(b)) => BoolOrDataConfig::from_bool(*b),
21 None => BoolOrDataConfig::default(),
22 }
23 }
24
25 pub fn or<F>(self, default: F) -> Self
26 where
27 F: FnOnce() -> Self,
28 {
29 match self.0 {
30 Some(..) => self,
31 None => default(),
32 }
33 }
34
35 pub fn unwrap_as_option<F>(self, default: F) -> Option<T>
36 where
37 F: FnOnce(Option<bool>) -> Option<T>,
38 {
39 match self.0 {
40 Some(BoolOr::Data(v)) => Some(v),
41 Some(BoolOr::Bool(b)) => default(Some(b)),
42 None => default(None),
43 }
44 }
45
46 pub fn map<F, N>(self, op: F) -> BoolOrDataConfig<N>
47 where
48 F: FnOnce(T) -> N,
49 {
50 match self.0 {
51 Some(BoolOr::Data(v)) => BoolOrDataConfig::from_obj(op(v)),
52 Some(BoolOr::Bool(b)) => BoolOrDataConfig::from_bool(b),
53 None => BoolOrDataConfig::default(),
54 }
55 }
56
57 pub fn is_true(&self) -> bool {
58 matches!(self.0, Some(BoolOr::Bool(true)))
59 }
60
61 pub fn is_false(&self) -> bool {
62 matches!(self.0, Some(BoolOr::Bool(false)))
63 }
64
65 pub fn is_obj(&self) -> bool {
66 matches!(self.0, Some(BoolOr::Data(_)))
67 }
68
69 pub fn into_inner(self) -> Option<BoolOr<T>> {
70 self.0
71 }
72
73 pub fn inner(&self) -> Option<BoolOr<&T>> {
74 match &self.0 {
75 Some(BoolOr::Data(v)) => Some(BoolOr::Data(v)),
76 Some(BoolOr::Bool(b)) => Some(BoolOr::Bool(*b)),
77 None => None,
78 }
79 }
80}
81
82impl<T> From<T> for BoolOrDataConfig<T> {
83 fn from(v: T) -> Self {
84 Self(Some(BoolOr::Data(v)))
85 }
86}
87
88impl<T> Default for BoolOrDataConfig<T> {
89 fn default() -> Self {
90 Self(Default::default())
91 }
92}
93
94impl<T> Merge for BoolOrDataConfig<T> {
95 #[inline]
96 fn merge(&mut self, other: Self) {
97 self.0.merge(other.0)
98 }
99}
100
101#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
102#[serde(untagged)]
103pub enum BoolOr<T> {
104 Bool(bool),
105 Data(T),
106}
107
108impl<'de, T> Deserialize<'de> for BoolOr<T>
109where
110 T: Deserialize<'de>,
111{
112 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
113 where
114 D: serde::Deserializer<'de>,
115 {
116 #[derive(Deserialize)]
117 #[serde(untagged)]
118 enum Deser<T> {
119 Bool(bool),
120 Obj(T),
121 EmptyObject(EmptyStruct),
122 }
123
124 #[derive(Deserialize)]
125 #[serde(deny_unknown_fields)]
126 struct EmptyStruct {}
127
128 use serde::__private::de;
129
130 let content = de::Content::deserialize(deserializer)?;
131
132 let deserializer = de::ContentRefDeserializer::<D::Error>::new(&content);
133
134 let res = Deser::deserialize(deserializer);
135
136 match res {
137 Ok(v) => Ok(match v {
138 Deser::Bool(v) => BoolOr::Bool(v),
139 Deser::Obj(v) => BoolOr::Data(v),
140 Deser::EmptyObject(_) => BoolOr::Bool(true),
141 }),
142 Err(..) => {
143 let d = de::ContentDeserializer::<D::Error>::new(content);
144 Ok(BoolOr::Data(T::deserialize(d)?))
145 }
146 }
147 }
148}