1use std::{
5 cmp::Ordering, collections::HashMap, hash::{Hash, Hasher}, mem, ptr
6};
7
8use super::{
9 AmadeusOrd, Bson, Date, DateTime, DateTimeWithoutTimezone, DateWithoutTimezone, Decimal, Enum, Group, IpAddr, Json, List, Time, TimeWithoutTimezone, Timezone, Url, Value, Webpage
10};
11
12#[derive(Clone, PartialEq, Debug)]
15pub enum ValueRequired {
16 Bool(bool),
19 U8(u8),
21 I8(i8),
23 U16(u16),
25 I16(i16),
27 U32(u32),
29 I32(i32),
31 U64(u64),
33 I64(i64),
35 F32(f32),
37 F64(f64),
39 Date(Date),
42 DateWithoutTimezone(DateWithoutTimezone),
45 Time(Time),
47 TimeWithoutTimezone(TimeWithoutTimezone),
49 DateTime(DateTime),
51 DateTimeWithoutTimezone(DateTimeWithoutTimezone),
53 Timezone(Timezone),
55 Decimal(Decimal),
57 Bson(Bson),
59 String(String),
61 Json(Json),
63 Enum(Enum),
65 Url(Url),
67 Webpage(Webpage<'static>),
69 IpAddr(IpAddr),
71
72 List(List<Value>),
75 Map(HashMap<Value, Value>),
77 Group(Group),
79}
80
81impl ValueRequired {
82 pub fn as_value<R>(&self, f: impl FnOnce(&Value) -> R) -> R {
83 #[allow(unsafe_code)]
84 let value = mem::ManuallyDrop::new(unsafe {
85 match self {
86 Self::Bool(value) => Value::Bool(ptr::read(value)),
87 Self::U8(value) => Value::U8(ptr::read(value)),
88 Self::I8(value) => Value::I8(ptr::read(value)),
89 Self::U16(value) => Value::U16(ptr::read(value)),
90 Self::I16(value) => Value::I16(ptr::read(value)),
91 Self::U32(value) => Value::U32(ptr::read(value)),
92 Self::I32(value) => Value::I32(ptr::read(value)),
93 Self::U64(value) => Value::U64(ptr::read(value)),
94 Self::I64(value) => Value::I64(ptr::read(value)),
95 Self::F32(value) => Value::F32(ptr::read(value)),
96 Self::F64(value) => Value::F64(ptr::read(value)),
97 Self::Date(value) => Value::Date(ptr::read(value)),
98 Self::DateWithoutTimezone(value) => Value::DateWithoutTimezone(ptr::read(value)),
99 Self::Time(value) => Value::Time(ptr::read(value)),
100 Self::TimeWithoutTimezone(value) => Value::TimeWithoutTimezone(ptr::read(value)),
101 Self::DateTime(value) => Value::DateTime(ptr::read(value)),
102 Self::DateTimeWithoutTimezone(value) => {
103 Value::DateTimeWithoutTimezone(ptr::read(value))
104 }
105 Self::Timezone(value) => Value::Timezone(ptr::read(value)),
106 Self::Decimal(value) => Value::Decimal(ptr::read(value)),
107 Self::Bson(value) => Value::Bson(ptr::read(value)),
108 Self::String(value) => Value::String(ptr::read(value)),
109 Self::Json(value) => Value::Json(ptr::read(value)),
110 Self::Enum(value) => Value::Enum(ptr::read(value)),
111 Self::Url(value) => Value::Url(ptr::read(value)),
112 Self::Webpage(value) => Value::Webpage(ptr::read(value)),
113 Self::IpAddr(value) => Value::IpAddr(ptr::read(value)),
114 Self::List(value) => Value::List(ptr::read(value)),
115 Self::Map(value) => Value::Map(ptr::read(value)),
116 Self::Group(value) => Value::Group(ptr::read(value)),
117 }
118 });
119 f(&value)
120 }
121}
122
123#[allow(clippy::derive_hash_xor_eq)]
124impl Hash for ValueRequired {
125 fn hash<H: Hasher>(&self, state: &mut H) {
126 match self {
127 Self::Bool(value) => {
128 0_u8.hash(state);
129 value.hash(state);
130 }
131 Self::U8(value) => {
132 1_u8.hash(state);
133 value.hash(state);
134 }
135 Self::I8(value) => {
136 2_u8.hash(state);
137 value.hash(state);
138 }
139 Self::U16(value) => {
140 3_u8.hash(state);
141 value.hash(state);
142 }
143 Self::I16(value) => {
144 4_u8.hash(state);
145 value.hash(state);
146 }
147 Self::U32(value) => {
148 5_u8.hash(state);
149 value.hash(state);
150 }
151 Self::I32(value) => {
152 6_u8.hash(state);
153 value.hash(state);
154 }
155 Self::U64(value) => {
156 7_u8.hash(state);
157 value.hash(state);
158 }
159 Self::I64(value) => {
160 8_u8.hash(state);
161 value.hash(state);
162 }
163 Self::F32(_value) => {
164 9_u8.hash(state);
165 }
166 Self::F64(_value) => {
167 10_u8.hash(state);
168 }
169 Self::Date(value) => {
170 11_u8.hash(state);
171 value.hash(state);
172 }
173 Self::DateWithoutTimezone(value) => {
174 11_u8.hash(state);
175 value.hash(state);
176 }
177 Self::Time(value) => {
178 12_u8.hash(state);
179 value.hash(state);
180 }
181 Self::TimeWithoutTimezone(value) => {
182 12_u8.hash(state);
183 value.hash(state);
184 }
185 Self::DateTime(value) => {
186 13_u8.hash(state);
187 value.hash(state);
188 }
189 Self::DateTimeWithoutTimezone(value) => {
190 13_u8.hash(state);
191 value.hash(state);
192 }
193 Self::Timezone(value) => {
194 13_u8.hash(state);
195 value.hash(state);
196 }
197 Self::Decimal(_value) => {
198 14_u8.hash(state);
199 }
200 Self::Bson(value) => {
201 15_u8.hash(state);
202 value.hash(state);
203 }
204 Self::String(value) => {
205 16_u8.hash(state);
206 value.hash(state);
207 }
208 Self::Json(value) => {
209 17_u8.hash(state);
210 value.hash(state);
211 }
212 Self::Enum(value) => {
213 18_u8.hash(state);
214 value.hash(state);
215 }
216 Self::Url(value) => {
217 19_u8.hash(state);
218 value.hash(state);
219 }
220 Self::Webpage(value) => {
221 20_u8.hash(state);
222 value.hash(state);
223 }
224 Self::IpAddr(value) => {
225 21_u8.hash(state);
226 value.hash(state);
227 }
228 Self::List(value) => {
229 22_u8.hash(state);
230 value.hash(state);
231 }
232 Self::Map(_value) => {
233 23_u8.hash(state);
234 }
235 Self::Group(_value) => {
236 24_u8.hash(state);
237 }
238 }
239 }
240}
241impl Eq for ValueRequired {}
242impl PartialOrd for ValueRequired {
243 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
244 match (self, other) {
245 (Self::Bool(a), Self::Bool(b)) => a.partial_cmp(b),
246 (Self::U8(a), Self::U8(b)) => a.partial_cmp(b),
247 (Self::I8(a), Self::I8(b)) => a.partial_cmp(b),
248 (Self::U16(a), Self::U16(b)) => a.partial_cmp(b),
249 (Self::I16(a), Self::I16(b)) => a.partial_cmp(b),
250 (Self::U32(a), Self::U32(b)) => a.partial_cmp(b),
251 (Self::I32(a), Self::I32(b)) => a.partial_cmp(b),
252 (Self::U64(a), Self::U64(b)) => a.partial_cmp(b),
253 (Self::I64(a), Self::I64(b)) => a.partial_cmp(b),
254 (Self::F32(a), Self::F32(b)) => a.partial_cmp(b),
255 (Self::F64(a), Self::F64(b)) => a.partial_cmp(b),
256 (Self::Date(a), Self::Date(b)) => a.partial_cmp(b),
257 (Self::DateWithoutTimezone(a), Self::DateWithoutTimezone(b)) => a.partial_cmp(b),
258 (Self::Time(a), Self::Time(b)) => a.partial_cmp(b),
259 (Self::TimeWithoutTimezone(a), Self::TimeWithoutTimezone(b)) => a.partial_cmp(b),
260 (Self::DateTime(a), Self::DateTime(b)) => a.partial_cmp(b),
261 (Self::DateTimeWithoutTimezone(a), Self::DateTimeWithoutTimezone(b)) => {
262 a.partial_cmp(b)
263 }
264 (Self::Timezone(a), Self::Timezone(b)) => a.partial_cmp(b),
265 (Self::Decimal(a), Self::Decimal(b)) => a.partial_cmp(b),
266 (Self::Bson(a), Self::Bson(b)) => a.partial_cmp(b),
267 (Self::String(a), Self::String(b)) => a.partial_cmp(b),
268 (Self::Json(a), Self::Json(b)) => a.partial_cmp(b),
269 (Self::Enum(a), Self::Enum(b)) => a.partial_cmp(b),
270 (Self::Url(a), Self::Url(b)) => a.partial_cmp(b),
271 (Self::Webpage(a), Self::Webpage(b)) => a.partial_cmp(b),
272 (Self::IpAddr(a), Self::IpAddr(b)) => a.partial_cmp(b),
273 (Self::List(a), Self::List(b)) => a.partial_cmp(b),
274 (Self::Map(_a), Self::Map(_b)) => None, (Self::Group(a), Self::Group(b)) => a.partial_cmp(b),
276 _ => None,
277 }
278 }
279}
280impl AmadeusOrd for ValueRequired {
281 fn amadeus_cmp(&self, other: &Self) -> Ordering {
282 match (self, other) {
283 (Self::Bool(a), Self::Bool(b)) => a.amadeus_cmp(b),
284 (Self::U8(a), Self::U8(b)) => a.amadeus_cmp(b),
285 (Self::I8(a), Self::I8(b)) => a.amadeus_cmp(b),
286 (Self::U16(a), Self::U16(b)) => a.amadeus_cmp(b),
287 (Self::I16(a), Self::I16(b)) => a.amadeus_cmp(b),
288 (Self::U32(a), Self::U32(b)) => a.amadeus_cmp(b),
289 (Self::I32(a), Self::I32(b)) => a.amadeus_cmp(b),
290 (Self::U64(a), Self::U64(b)) => a.amadeus_cmp(b),
291 (Self::I64(a), Self::I64(b)) => a.amadeus_cmp(b),
292 (Self::F32(a), Self::F32(b)) => a.amadeus_cmp(b),
293 (Self::F64(a), Self::F64(b)) => a.amadeus_cmp(b),
294 (Self::Date(a), Self::Date(b)) => a.amadeus_cmp(b),
295 (Self::DateWithoutTimezone(a), Self::DateWithoutTimezone(b)) => a.amadeus_cmp(b),
296 (Self::Time(a), Self::Time(b)) => a.amadeus_cmp(b),
297 (Self::TimeWithoutTimezone(a), Self::TimeWithoutTimezone(b)) => a.amadeus_cmp(b),
298 (Self::DateTime(a), Self::DateTime(b)) => a.amadeus_cmp(b),
299 (Self::DateTimeWithoutTimezone(a), Self::DateTimeWithoutTimezone(b)) => {
300 a.amadeus_cmp(b)
301 }
302 (Self::Timezone(a), Self::Timezone(b)) => a.amadeus_cmp(b),
303 (Self::Decimal(a), Self::Decimal(b)) => a.amadeus_cmp(b),
304 (Self::Bson(a), Self::Bson(b)) => a.amadeus_cmp(b),
305 (Self::String(a), Self::String(b)) => a.amadeus_cmp(b),
306 (Self::Json(a), Self::Json(b)) => a.amadeus_cmp(b),
307 (Self::Enum(a), Self::Enum(b)) => a.amadeus_cmp(b),
308 (Self::Url(a), Self::Url(b)) => a.amadeus_cmp(b),
309 (Self::Webpage(a), Self::Webpage(b)) => a.amadeus_cmp(b),
310 (Self::IpAddr(a), Self::IpAddr(b)) => a.amadeus_cmp(b),
311 (Self::List(a), Self::List(b)) => a.amadeus_cmp(b),
312 (Self::Map(a), Self::Map(b)) => a.amadeus_cmp(b),
313 (Self::Group(a), Self::Group(b)) => a.amadeus_cmp(b),
314 _ => unimplemented!(),
315 }
316 }
317}
318
319impl From<ValueRequired> for Value {
320 fn from(value: ValueRequired) -> Self {
321 match value {
322 ValueRequired::Bool(value) => Self::Bool(value),
323 ValueRequired::U8(value) => Self::U8(value),
324 ValueRequired::I8(value) => Self::I8(value),
325 ValueRequired::U16(value) => Self::U16(value),
326 ValueRequired::I16(value) => Self::I16(value),
327 ValueRequired::U32(value) => Self::U32(value),
328 ValueRequired::I32(value) => Self::I32(value),
329 ValueRequired::U64(value) => Self::U64(value),
330 ValueRequired::I64(value) => Self::I64(value),
331 ValueRequired::F32(value) => Self::F32(value),
332 ValueRequired::F64(value) => Self::F64(value),
333 ValueRequired::Date(value) => Self::Date(value),
334 ValueRequired::DateWithoutTimezone(value) => Self::DateWithoutTimezone(value),
335 ValueRequired::Time(value) => Self::Time(value),
336 ValueRequired::TimeWithoutTimezone(value) => Self::TimeWithoutTimezone(value),
337 ValueRequired::DateTime(value) => Self::DateTime(value),
338 ValueRequired::DateTimeWithoutTimezone(value) => Self::DateTimeWithoutTimezone(value),
339 ValueRequired::Timezone(value) => Self::Timezone(value),
340 ValueRequired::Decimal(value) => Self::Decimal(value),
341 ValueRequired::Bson(value) => Self::Bson(value),
342 ValueRequired::String(value) => Self::String(value),
343 ValueRequired::Json(value) => Self::Json(value),
344 ValueRequired::Enum(value) => Self::Enum(value),
345 ValueRequired::Url(value) => Self::Url(value),
346 ValueRequired::Webpage(value) => Self::Webpage(value),
347 ValueRequired::IpAddr(value) => Self::IpAddr(value),
348 ValueRequired::List(value) => Self::List(value),
349 ValueRequired::Map(value) => Self::Map(value),
350 ValueRequired::Group(value) => Self::Group(value),
351 }
352 }
353}
354
355impl From<Value> for Option<ValueRequired> {
356 fn from(value: Value) -> Self {
357 Some(match value {
358 Value::Bool(value) => ValueRequired::Bool(value),
359 Value::U8(value) => ValueRequired::U8(value),
360 Value::I8(value) => ValueRequired::I8(value),
361 Value::U16(value) => ValueRequired::U16(value),
362 Value::I16(value) => ValueRequired::I16(value),
363 Value::U32(value) => ValueRequired::U32(value),
364 Value::I32(value) => ValueRequired::I32(value),
365 Value::U64(value) => ValueRequired::U64(value),
366 Value::I64(value) => ValueRequired::I64(value),
367 Value::F32(value) => ValueRequired::F32(value),
368 Value::F64(value) => ValueRequired::F64(value),
369 Value::Date(value) => ValueRequired::Date(value),
370 Value::DateWithoutTimezone(value) => ValueRequired::DateWithoutTimezone(value),
371 Value::Time(value) => ValueRequired::Time(value),
372 Value::TimeWithoutTimezone(value) => ValueRequired::TimeWithoutTimezone(value),
373 Value::DateTime(value) => ValueRequired::DateTime(value),
374 Value::DateTimeWithoutTimezone(value) => ValueRequired::DateTimeWithoutTimezone(value),
375 Value::Timezone(value) => ValueRequired::Timezone(value),
376 Value::Decimal(value) => ValueRequired::Decimal(value),
377 Value::Bson(value) => ValueRequired::Bson(value),
378 Value::String(value) => ValueRequired::String(value),
379 Value::Json(value) => ValueRequired::Json(value),
380 Value::Enum(value) => ValueRequired::Enum(value),
381 Value::Url(value) => ValueRequired::Url(value),
382 Value::Webpage(value) => ValueRequired::Webpage(value),
383 Value::IpAddr(value) => ValueRequired::IpAddr(value),
384 Value::List(value) => ValueRequired::List(value),
385 Value::Map(value) => ValueRequired::Map(value),
386 Value::Group(value) => ValueRequired::Group(value),
387 Value::Option(_) => return None,
388 })
389 }
390}
391
392