1use core::fmt;
3
4#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
6pub enum JsonKind {
7 Null,
8 Boolean,
9 Number,
10 String,
11 Array,
12 Object,
13}
14
15impl std::ops::BitOr for JsonKind {
16 type Output = JsonKindSet;
17
18 fn bitor(self, other: Self) -> JsonKindSet {
19 JsonKindSet::from(self) | JsonKindSet::from(other)
20 }
21}
22
23impl std::ops::BitOr<JsonKindSet> for JsonKind {
24 type Output = JsonKindSet;
25
26 fn bitor(self, other: JsonKindSet) -> JsonKindSet {
27 JsonKindSet::from(self) | other
28 }
29}
30
31impl std::ops::BitAnd for JsonKind {
32 type Output = JsonKindSet;
33
34 fn bitand(self, other: Self) -> JsonKindSet {
35 JsonKindSet::from(self) & JsonKindSet::from(other)
36 }
37}
38
39impl std::ops::BitAnd<JsonKindSet> for JsonKind {
40 type Output = JsonKindSet;
41
42 fn bitand(self, other: JsonKindSet) -> JsonKindSet {
43 JsonKindSet::from(self) & other
44 }
45}
46
47impl fmt::Display for JsonKind {
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 match self {
50 Self::Null => write!(f, "null"),
51 Self::Boolean => write!(f, "boolean"),
52 Self::Number => write!(f, "number"),
53 Self::String => write!(f, "string"),
54 Self::Array => write!(f, "array"),
55 Self::Object => write!(f, "object"),
56 }
57 }
58}
59
60macro_rules! kind_set {
61 ($($id:ident ($const:ident): $mask:literal),*) => {
62 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
64 pub struct JsonKindSet(u8);
65
66 impl JsonKindSet {
67 $(
68 pub const $const: Self = Self($mask);
69 )*
70
71 pub const fn all() -> Self {
72 Self($($mask)|*)
73 }
74 }
75
76 impl std::ops::BitOr<JsonKind> for JsonKindSet {
77 type Output = Self;
78
79 fn bitor(self, other: JsonKind) -> Self {
80 match other {
81 $(
82 JsonKind::$id => Self(self.0 | $mask)
83 ),*
84 }
85 }
86 }
87
88 impl std::ops::BitOrAssign<JsonKind> for JsonKindSet {
89 fn bitor_assign(&mut self, other: JsonKind) {
90 match other {
91 $(
92 JsonKind::$id => self.0 |= $mask
93 ),*
94 }
95 }
96 }
97
98 impl std::ops::BitAnd<JsonKind> for JsonKindSet {
99 type Output = Self;
100
101 fn bitand(self, other: JsonKind) -> Self {
102 match other {
103 $(
104 JsonKind::$id => Self(self.0 & $mask)
105 ),*
106 }
107 }
108 }
109
110 impl std::ops::BitAndAssign<JsonKind> for JsonKindSet {
111 fn bitand_assign(&mut self, other: JsonKind) {
112 match other {
113 $(
114 JsonKind::$id => self.0 &= $mask
115 ),*
116 }
117 }
118 }
119
120 impl From<JsonKind> for JsonKindSet {
121 fn from(value: JsonKind) -> Self {
122 match value {
123 $(
124 JsonKind::$id => Self($mask)
125 ),*
126 }
127 }
128 }
129
130 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
131 pub struct JsonKindSetIter(u8);
132
133 impl Iterator for JsonKindSetIter {
134 type Item = JsonKind;
135
136 fn size_hint(&self) -> (usize, Option<usize>) {
137 let len = self.0.count_ones() as usize;
138 (len, Some(len))
139 }
140
141 fn next(&mut self) -> Option<JsonKind> {
142 $(
143 if self.0 & $mask != 0 {
144 self.0 &= !$mask;
145 return Some(JsonKind::$id)
146 }
147 )*
148
149 None
150 }
151 }
152
153 impl DoubleEndedIterator for JsonKindSetIter {
154 fn next_back(&mut self) -> Option<JsonKind> {
155 let mut result = None;
156
157 $(
158 if self.0 & $mask != 0 {
159 result = Some((JsonKind::$id, $mask));
160 }
161 )*
162
163 result.map(|(kind, mask)| {
164 self.0 &= !mask;
165 kind
166 })
167 }
168 }
169
170 impl std::iter::FusedIterator for JsonKindSetIter {}
171 impl std::iter::ExactSizeIterator for JsonKindSetIter {}
172 };
173}
174
175kind_set! {
176 Null (NULL): 0b000001,
177 Boolean (BOOLEAN): 0b000010,
178 Number (NUMBER): 0b000100,
179 String (STRING): 0b001000,
180 Array (ARRAY): 0b010000,
181 Object (OBJECT): 0b100000
182}
183
184impl JsonKindSet {
185 pub const fn none() -> Self {
186 Self(0)
187 }
188
189 pub const fn len(&self) -> usize {
190 self.0.count_ones() as usize
191 }
192
193 pub const fn is_empty(&self) -> bool {
194 self.0 == 0
195 }
196
197 pub fn iter(&self) -> JsonKindSetIter {
198 JsonKindSetIter(self.0)
199 }
200
201 pub fn as_disjunction(self) -> JsonKindSetDisjunction {
214 JsonKindSetDisjunction(self)
215 }
216
217 pub fn as_conjunction(self) -> JsonKindSetConjunction {
230 JsonKindSetConjunction(self)
231 }
232}
233
234impl std::ops::BitOr for JsonKindSet {
235 type Output = Self;
236
237 fn bitor(self, other: Self) -> Self {
238 Self(self.0 | other.0)
239 }
240}
241
242impl std::ops::BitOrAssign for JsonKindSet {
243 fn bitor_assign(&mut self, other: Self) {
244 self.0 |= other.0
245 }
246}
247
248impl std::ops::BitAnd for JsonKindSet {
249 type Output = Self;
250
251 fn bitand(self, other: Self) -> Self {
252 Self(self.0 & other.0)
253 }
254}
255
256impl std::ops::BitAndAssign for JsonKindSet {
257 fn bitand_assign(&mut self, other: Self) {
258 self.0 &= other.0
259 }
260}
261
262impl IntoIterator for &JsonKindSet {
263 type IntoIter = JsonKindSetIter;
264 type Item = JsonKind;
265
266 fn into_iter(self) -> JsonKindSetIter {
267 self.iter()
268 }
269}
270
271impl IntoIterator for JsonKindSet {
272 type IntoIter = JsonKindSetIter;
273 type Item = JsonKind;
274
275 fn into_iter(self) -> JsonKindSetIter {
276 self.iter()
277 }
278}
279
280impl fmt::Display for JsonKindSet {
281 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
282 for (i, kind) in self.into_iter().enumerate() {
283 if i > 0 {
284 f.write_str(", ")?;
285 }
286
287 kind.fmt(f)?;
288 }
289
290 Ok(())
291 }
292}
293
294#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
296pub struct JsonKindSetDisjunction(pub JsonKindSet);
297
298impl fmt::Display for JsonKindSetDisjunction {
299 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
300 if self.0 == JsonKindSet::all() {
301 f.write_str("anything")
302 } else {
303 let mut iter = self.0.into_iter();
304 match iter.next_back() {
305 Some(last) => {
306 if let Some(first) = iter.next() {
307 first.fmt(f)?;
308 for k in iter {
309 f.write_str(", ")?;
310 k.fmt(f)?;
311 }
312 f.write_str(" or ")?;
313 }
314
315 last.fmt(f)
316 }
317 None => f.write_str("nothing"),
318 }
319 }
320 }
321}
322
323#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
325pub struct JsonKindSetConjunction(pub JsonKindSet);
326
327impl fmt::Display for JsonKindSetConjunction {
328 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
329 if self.0 == JsonKindSet::all() {
330 f.write_str("anything")
331 } else {
332 let mut iter = self.0.into_iter();
333 match iter.next_back() {
334 Some(last) => {
335 if let Some(first) = iter.next() {
336 first.fmt(f)?;
337 for k in iter {
338 f.write_str(", ")?;
339 k.fmt(f)?;
340 }
341 f.write_str(" and ")?;
342 }
343
344 last.fmt(f)
345 }
346 None => f.write_str("nothing"),
347 }
348 }
349 }
350}