1use core::fmt;
3
4#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
6pub enum Kind {
7 Null,
8 Boolean,
9 Number,
10 String,
11 Array,
12 Object,
13}
14
15impl std::ops::BitOr for Kind {
16 type Output = KindSet;
17
18 fn bitor(self, other: Self) -> KindSet {
19 KindSet::from(self) | KindSet::from(other)
20 }
21}
22
23impl std::ops::BitOr<KindSet> for Kind {
24 type Output = KindSet;
25
26 fn bitor(self, other: KindSet) -> KindSet {
27 KindSet::from(self) | other
28 }
29}
30
31impl std::ops::BitAnd for Kind {
32 type Output = KindSet;
33
34 fn bitand(self, other: Self) -> KindSet {
35 KindSet::from(self) & KindSet::from(other)
36 }
37}
38
39impl std::ops::BitAnd<KindSet> for Kind {
40 type Output = KindSet;
41
42 fn bitand(self, other: KindSet) -> KindSet {
43 KindSet::from(self) & other
44 }
45}
46
47impl fmt::Display for Kind {
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 KindSet(u8);
65
66 impl KindSet {
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<Kind> for KindSet {
77 type Output = Self;
78
79 fn bitor(self, other: Kind) -> Self {
80 match other {
81 $(
82 Kind::$id => Self(self.0 | $mask)
83 ),*
84 }
85 }
86 }
87
88 impl std::ops::BitOrAssign<Kind> for KindSet {
89 fn bitor_assign(&mut self, other: Kind) {
90 match other {
91 $(
92 Kind::$id => self.0 |= $mask
93 ),*
94 }
95 }
96 }
97
98 impl std::ops::BitAnd<Kind> for KindSet {
99 type Output = Self;
100
101 fn bitand(self, other: Kind) -> Self {
102 match other {
103 $(
104 Kind::$id => Self(self.0 & $mask)
105 ),*
106 }
107 }
108 }
109
110 impl std::ops::BitAndAssign<Kind> for KindSet {
111 fn bitand_assign(&mut self, other: Kind) {
112 match other {
113 $(
114 Kind::$id => self.0 &= $mask
115 ),*
116 }
117 }
118 }
119
120 impl From<Kind> for KindSet {
121 fn from(value: Kind) -> Self {
122 match value {
123 $(
124 Kind::$id => Self($mask)
125 ),*
126 }
127 }
128 }
129
130 #[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
131 pub struct KindSetIter(u8);
132
133 impl Iterator for KindSetIter {
134 type Item = Kind;
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<Kind> {
142 $(
143 if self.0 & $mask != 0 {
144 self.0 &= !$mask;
145 return Some(Kind::$id)
146 }
147 )*
148
149 None
150 }
151 }
152
153 impl DoubleEndedIterator for KindSetIter {
154 fn next_back(&mut self) -> Option<Kind> {
155 let mut result = None;
156
157 $(
158 if self.0 & $mask != 0 {
159 result = Some((Kind::$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 KindSetIter {}
171 impl std::iter::ExactSizeIterator for KindSetIter {}
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 KindSet {
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) -> KindSetIter {
198 KindSetIter(self.0)
199 }
200
201 pub fn as_disjunction(self) -> KindSetDisjunction {
214 KindSetDisjunction(self)
215 }
216
217 pub fn as_conjunction(self) -> KindSetConjunction {
230 KindSetConjunction(self)
231 }
232}
233
234impl std::ops::BitOr for KindSet {
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 KindSet {
243 fn bitor_assign(&mut self, other: Self) {
244 self.0 |= other.0
245 }
246}
247
248impl std::ops::BitAnd for KindSet {
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 KindSet {
257 fn bitand_assign(&mut self, other: Self) {
258 self.0 &= other.0
259 }
260}
261
262impl<'a> IntoIterator for &'a KindSet {
263 type IntoIter = KindSetIter;
264 type Item = Kind;
265
266 fn into_iter(self) -> KindSetIter {
267 self.iter()
268 }
269}
270
271impl IntoIterator for KindSet {
272 type IntoIter = KindSetIter;
273 type Item = Kind;
274
275 fn into_iter(self) -> KindSetIter {
276 self.iter()
277 }
278}
279
280impl fmt::Display for KindSet {
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 KindSetDisjunction(pub KindSet);
297
298impl fmt::Display for KindSetDisjunction {
299 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
300 if self.0 == KindSet::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 KindSetConjunction(pub KindSet);
326
327impl fmt::Display for KindSetConjunction {
328 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
329 if self.0 == KindSet::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}