1use std::{fmt, str::FromStr};
2
3use parse_link_header::LinkMap;
4use serde::de::{self, Visitor};
5
6pub struct NextLink(pub String);
7
8pub fn next_link(l: &LinkMap) -> Option<NextLink> {
9 l.get(&Some("next".to_string()))
10 .map(|link| link.raw_uri.to_string())
11 .map(NextLink)
12}
13
14pub mod date_format {
15 use chrono::NaiveDate;
16 use serde::{self, Deserialize, Deserializer};
17
18 pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<NaiveDate>, D::Error>
26 where
27 D: Deserializer<'de>,
28 {
29 let s: Option<String> = Option::deserialize(deserializer)?;
30 if let Some(s) = s {
31 if s.is_empty() {
32 Ok(None)
33 } else {
34 match serde_json::from_str::<NaiveDate>(&format!("\"{}\"", s)) {
36 Ok(t) => Ok(Some(t)),
37 Err(e) => Err(serde::de::Error::custom(format!(
38 "deserializing {} as NaiveDate failed: {}",
39 s, e
40 ))),
41 }
42 }
43 } else {
44 Ok(None)
45 }
46 }
47}
48
49pub mod date_time_format {
50 use chrono::{DateTime, TimeZone, Utc};
51 use serde::{self, Deserialize, Deserializer};
52
53 const FORMAT: &str = "%Y-%m-%dT%H:%M:%S%:z";
55
56 pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<DateTime<Utc>>, D::Error>
64 where
65 D: Deserializer<'de>,
66 {
67 let s: Option<String> = Option::deserialize(deserializer)?;
68 if let Some(mut s) = s {
69 match serde_json::from_str::<DateTime<Utc>>(&format!("\"{}\"", s)) {
71 Ok(t) => Ok(Some(t)),
72 Err(_) => {
73 match Utc.datetime_from_str(&s, "%Y-%m-%dT%H:%M:%S%.3fZ") {
75 Ok(t) => Ok(Some(t)),
76 Err(_) => match Utc.datetime_from_str(&s, FORMAT) {
77 Ok(t) => Ok(Some(t)),
78 Err(_) => match Utc.datetime_from_str(&s, "%+") {
79 Ok(t) => Ok(Some(t)),
80 Err(_) => match chrono::NaiveDate::parse_from_str(&s, "%Y-%m-%d") {
81 Ok(d) => Ok(Some(DateTime::<Utc>::from_utc(
82 chrono::NaiveDateTime::new(
83 d,
84 chrono::NaiveTime::from_hms_opt(0, 0, 0).unwrap(),
85 ),
86 Utc,
87 ))),
88 Err(_) => {
89 s = format!("{}+00:00", s);
90 match Utc.datetime_from_str(&s, FORMAT) {
91 Ok(r) => Ok(Some(r)),
92 Err(_) => match Utc.datetime_from_str(&s, "%+") {
93 Ok(d) => Ok(Some(d)),
94 Err(e) => Err(serde::de::Error::custom(format!(
95 "deserializing {} as DateTime<Utc> failed: {}",
96 s, e
97 ))),
98 },
99 }
100 }
101 },
102 },
103 },
104 }
105 }
106 }
107 } else {
108 Ok(None)
109 }
110 }
111}
112
113pub mod deserialize_empty_url {
114 use serde::{self, Deserialize, Deserializer};
115
116 pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<url::Url>, D::Error>
124 where
125 D: Deserializer<'de>,
126 {
127 if let Ok(s) = String::deserialize(deserializer) {
128 if s.is_empty() {
129 return Ok(None);
130 }
131
132 match url::Url::parse(&s) {
133 Ok(u) => return Ok(Some(u)),
134 Err(e) => {
135 return Err(serde::de::Error::custom(format!(
136 "error url parsing {}: {}",
137 s, e
138 )))
139 }
140 }
141 }
142
143 Ok(None)
144 }
145}
146
147pub mod deserialize_null_string {
148 use serde::{self, Deserialize, Deserializer};
149
150 pub fn deserialize<'de, D>(deserializer: D) -> Result<String, D::Error>
158 where
159 D: Deserializer<'de>,
160 {
161 let s = String::deserialize(deserializer).unwrap_or_default();
162
163 Ok(s)
164 }
165}
166
167struct BoolVisitor;
168
169impl Visitor<'_> for BoolVisitor {
170 type Value = bool;
171
172 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
173 formatter.write_str("a boolean")
174 }
175
176 fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
177 where
178 E: de::Error,
179 {
180 Ok(value)
181 }
182
183 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
184 where
185 E: de::Error,
186 {
187 match FromStr::from_str(value) {
188 Ok(s) => Ok(s),
189 Err(_) => Err(de::Error::invalid_value(
190 de::Unexpected::Str(value),
191 &"bool",
192 )),
193 }
194 }
195
196 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
197 where
198 E: de::Error,
199 {
200 match FromStr::from_str(&value) {
201 Ok(s) => Ok(s),
202 Err(_) => Err(de::Error::invalid_value(
203 de::Unexpected::Str(&value),
204 &"bool",
205 )),
206 }
207 }
208}
209
210pub mod deserialize_null_boolean {
211 use serde::{self, Deserializer};
212
213 pub fn deserialize<'de, D>(deserializer: D) -> Result<bool, D::Error>
221 where
222 D: Deserializer<'de>,
223 {
224 let s = deserializer
225 .deserialize_bool(crate::utils::BoolVisitor)
226 .unwrap_or_default();
227
228 Ok(s)
229 }
230}
231
232struct I32Visitor;
233
234impl Visitor<'_> for I32Visitor {
235 type Value = i32;
236
237 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
238 formatter.write_str("an integer between -2^31 and 2^31")
239 }
240
241 fn visit_i8<E>(self, value: i8) -> Result<Self::Value, E>
242 where
243 E: de::Error,
244 {
245 Ok(value as i32)
246 }
247
248 fn visit_i16<E>(self, value: i16) -> Result<Self::Value, E>
249 where
250 E: de::Error,
251 {
252 Ok(value as i32)
253 }
254
255 fn visit_i32<E>(self, value: i32) -> Result<Self::Value, E>
256 where
257 E: de::Error,
258 {
259 Ok(value)
260 }
261
262 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
263 where
264 E: de::Error,
265 {
266 use std::i32;
267 if value >= i64::from(i32::MIN) && value <= i64::from(i32::MAX) {
268 Ok(value as i32)
269 } else {
270 Err(E::custom(format!("i32 out of range: {}", value)))
271 }
272 }
273
274 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
275 where
276 E: de::Error,
277 {
278 Ok(value as i32)
279 }
280}
281
282pub mod deserialize_null_i32 {
283 use serde::{self, Deserializer};
284
285 pub fn deserialize<'de, D>(deserializer: D) -> Result<i32, D::Error>
293 where
294 D: Deserializer<'de>,
295 {
296 let s = deserializer
297 .deserialize_i32(crate::utils::I32Visitor)
298 .unwrap_or_default();
299
300 Ok(s)
301 }
302}
303
304struct I64Visitor;
305
306impl Visitor<'_> for I64Visitor {
307 type Value = i64;
308
309 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
310 formatter.write_str("an integer")
311 }
312
313 fn visit_i8<E>(self, value: i8) -> Result<Self::Value, E>
314 where
315 E: de::Error,
316 {
317 Ok(value as i64)
318 }
319
320 fn visit_i16<E>(self, value: i16) -> Result<Self::Value, E>
321 where
322 E: de::Error,
323 {
324 Ok(value as i64)
325 }
326
327 fn visit_i32<E>(self, value: i32) -> Result<Self::Value, E>
328 where
329 E: de::Error,
330 {
331 Ok(value as i64)
332 }
333
334 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
335 where
336 E: de::Error,
337 {
338 Ok(value)
339 }
340
341 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
342 where
343 E: de::Error,
344 {
345 Ok(value as i64)
346 }
347}
348
349pub mod deserialize_null_i64 {
350 use serde::{self, Deserializer};
351
352 pub fn deserialize<'de, D>(deserializer: D) -> Result<i64, D::Error>
360 where
361 D: Deserializer<'de>,
362 {
363 let s = deserializer
364 .deserialize_i64(crate::utils::I64Visitor)
365 .unwrap_or_default();
366
367 Ok(s)
368 }
369}
370
371struct F32Visitor;
372
373impl Visitor<'_> for F32Visitor {
374 type Value = f32;
375
376 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
377 formatter.write_str("a float between -2^31 and 2^31")
378 }
379
380 fn visit_i8<E>(self, value: i8) -> Result<Self::Value, E>
381 where
382 E: de::Error,
383 {
384 Ok(value as f32)
385 }
386
387 fn visit_i16<E>(self, value: i16) -> Result<Self::Value, E>
388 where
389 E: de::Error,
390 {
391 Ok(value as f32)
392 }
393
394 fn visit_i32<E>(self, value: i32) -> Result<Self::Value, E>
395 where
396 E: de::Error,
397 {
398 Ok(value as f32)
399 }
400
401 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
402 where
403 E: de::Error,
404 {
405 use std::i32;
406 if value >= i64::from(i32::MIN) && value <= i64::from(i32::MAX) {
407 Ok(value as f32)
408 } else {
409 Err(E::custom(format!("f32 out of range: {}", value)))
410 }
411 }
412
413 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
414 where
415 E: de::Error,
416 {
417 Ok(value as f32)
418 }
419
420 fn visit_f32<E>(self, value: f32) -> Result<Self::Value, E>
421 where
422 E: de::Error,
423 {
424 Ok(value)
425 }
426
427 fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E>
428 where
429 E: de::Error,
430 {
431 use std::f32;
432 if value >= f64::from(f32::MIN) && value <= f64::from(f32::MAX) {
433 Ok(value as f32)
434 } else {
435 Err(E::custom(format!("f32 out of range: {}", value)))
436 }
437 }
438}
439
440pub mod deserialize_null_f32 {
441 use serde::{self, Deserializer};
442
443 pub fn deserialize<'de, D>(deserializer: D) -> Result<f32, D::Error>
451 where
452 D: Deserializer<'de>,
453 {
454 let s = deserializer
455 .deserialize_f32(crate::utils::F32Visitor)
456 .unwrap_or_default();
457
458 Ok(s)
459 }
460}
461
462struct F64Visitor;
463
464impl Visitor<'_> for F64Visitor {
465 type Value = f64;
466
467 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
468 formatter.write_str("a float")
469 }
470
471 fn visit_i8<E>(self, value: i8) -> Result<Self::Value, E>
472 where
473 E: de::Error,
474 {
475 Ok(value as f64)
476 }
477
478 fn visit_i16<E>(self, value: i16) -> Result<Self::Value, E>
479 where
480 E: de::Error,
481 {
482 Ok(value as f64)
483 }
484
485 fn visit_i32<E>(self, value: i32) -> Result<Self::Value, E>
486 where
487 E: de::Error,
488 {
489 Ok(value as f64)
490 }
491
492 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
493 where
494 E: de::Error,
495 {
496 Ok(value as f64)
497 }
498
499 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
500 where
501 E: de::Error,
502 {
503 Ok(value as f64)
504 }
505
506 fn visit_f32<E>(self, value: f32) -> Result<Self::Value, E>
507 where
508 E: de::Error,
509 {
510 Ok(value as f64)
511 }
512
513 fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E>
514 where
515 E: de::Error,
516 {
517 Ok(value)
518 }
519}
520
521pub mod deserialize_null_f64 {
522 use serde::{self, Deserializer};
523
524 pub fn deserialize<'de, D>(deserializer: D) -> Result<f64, D::Error>
532 where
533 D: Deserializer<'de>,
534 {
535 let s = deserializer
536 .deserialize_f64(crate::utils::F64Visitor)
537 .unwrap_or_default();
538
539 Ok(s)
540 }
541}
542
543pub fn zero_i32(num: &i32) -> bool {
544 *num == 0
545}
546
547pub fn zero_i64(num: &i64) -> bool {
548 *num == 0
549}
550
551pub fn zero_f32(num: &f32) -> bool {
552 *num == 0.0
553}
554
555pub fn zero_f64(num: &f64) -> bool {
556 *num == 0.0
557}
558
559pub mod google_calendar_date_time_format {
560 use chrono::{DateTime, Utc};
561 use serde::{self, Serializer};
562
563 const FORMAT: &str = "%Y-%m-%dT%H:%M:%S%.3fZ";
565
566 pub fn serialize<S>(date: &Option<DateTime<Utc>>, serializer: S) -> Result<S::Ok, S::Error>
574 where
575 S: Serializer,
576 {
577 if date.is_some() {
578 let s = format!("{}", date.unwrap().format(FORMAT));
579 return serializer.serialize_str(&s);
580 }
581
582 serializer.serialize_none()
583 }
584}
585
586struct VectorVisitor<T>(std::marker::PhantomData<fn() -> Vec<T>>);
587
588impl<'de, T> Visitor<'de> for VectorVisitor<T>
589where
590 T: de::Deserialize<'de>,
591{
592 type Value = Vec<T>;
593
594 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
595 formatter.write_str("a very special vector")
596 }
597
598 fn visit_seq<A: de::SeqAccess<'de>>(self, mut access: A) -> Result<Self::Value, A::Error> {
599 let mut things: Vec<T> = Default::default();
600
601 while let Some(t) = access.next_element::<T>()? {
604 things.push(t);
605 }
606
607 Ok(things)
608 }
609}
610
611pub mod deserialize_null_vector {
612 use serde::{self, Deserialize, Deserializer};
613
614 use super::VectorVisitor;
615
616 pub fn deserialize<'de, T, D>(deserializer: D) -> Result<Vec<T>, D::Error>
624 where
625 T: Deserialize<'de>,
626 D: Deserializer<'de>,
627 {
628 if let Ok(r) = deserializer.deserialize_seq(VectorVisitor::<T>(std::marker::PhantomData)) {
629 return Ok(r);
630 }
631
632 Ok(Default::default())
633 }
634}
635
636#[cfg(test)]
637mod tests {
638 use super::next_link;
639
640 #[test]
641 fn test_hyperx_next_link_compat() {
642 let value = "<https://previous-link>; rel=\"prev\", <https://next-link>; rel=\"next\", <https://last-link>; rel=\"last\", <https://first-link>; rel=\"first\"";
643
644 let link = parse_link_header::parse(value).unwrap();
645 let next = next_link(&link).unwrap().0;
646
647 assert_eq!("https://next-link", next);
648 }
649}