1use serde::de::{self, Deserializer, SeqAccess, Visitor};
10use std::fmt;
11
12struct U64OrStringVisitor;
15
16impl<'de> Visitor<'de> for U64OrStringVisitor {
17 type Value = u64;
18
19 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
20 f.write_str("u64 or string-encoded u64")
21 }
22
23 fn visit_u64<E: de::Error>(self, v: u64) -> Result<u64, E> {
24 Ok(v)
25 }
26
27 fn visit_i64<E: de::Error>(self, v: i64) -> Result<u64, E> {
28 u64::try_from(v).map_err(|_| E::custom(format!("negative value {v} cannot be u64")))
29 }
30
31 fn visit_f64<E: de::Error>(self, v: f64) -> Result<u64, E> {
32 if v >= 0.0 && v <= u64::MAX as f64 {
33 Ok(v as u64)
34 } else {
35 Err(E::custom(format!("f64 {v} out of u64 range")))
36 }
37 }
38
39 fn visit_str<E: de::Error>(self, v: &str) -> Result<u64, E> {
40 v.parse().map_err(E::custom)
41 }
42}
43
44struct I64OrStringVisitor;
45
46impl<'de> Visitor<'de> for I64OrStringVisitor {
47 type Value = i64;
48
49 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
50 f.write_str("i64 or string-encoded i64")
51 }
52
53 fn visit_u64<E: de::Error>(self, v: u64) -> Result<i64, E> {
54 i64::try_from(v).map_err(|_| E::custom(format!("u64 {v} overflows i64")))
55 }
56
57 fn visit_i64<E: de::Error>(self, v: i64) -> Result<i64, E> {
58 Ok(v)
59 }
60
61 fn visit_f64<E: de::Error>(self, v: f64) -> Result<i64, E> {
62 if v >= i64::MIN as f64 && v <= i64::MAX as f64 {
63 Ok(v as i64)
64 } else {
65 Err(E::custom(format!("f64 {v} out of i64 range")))
66 }
67 }
68
69 fn visit_str<E: de::Error>(self, v: &str) -> Result<i64, E> {
70 v.parse().map_err(E::custom)
71 }
72}
73
74pub fn deserialize_u64<'de, D: Deserializer<'de>>(d: D) -> Result<u64, D::Error> {
78 d.deserialize_any(U64OrStringVisitor)
79}
80
81pub fn deserialize_i64<'de, D: Deserializer<'de>>(d: D) -> Result<i64, D::Error> {
83 d.deserialize_any(I64OrStringVisitor)
84}
85
86pub fn deserialize_option_u64<'de, D: Deserializer<'de>>(d: D) -> Result<Option<u64>, D::Error> {
93 struct V;
94 impl<'de> Visitor<'de> for V {
95 type Value = Option<u64>;
96 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
97 f.write_str("null, u64, or string-encoded u64")
98 }
99 fn visit_unit<E: de::Error>(self) -> Result<Option<u64>, E> {
100 Ok(None)
101 }
102 fn visit_none<E: de::Error>(self) -> Result<Option<u64>, E> {
103 Ok(None)
104 }
105 fn visit_some<D2: Deserializer<'de>>(self, d: D2) -> Result<Option<u64>, D2::Error> {
106 deserialize_u64(d).map(Some)
107 }
108 }
109 d.deserialize_option(V)
110}
111
112pub fn deserialize_option_i64<'de, D: Deserializer<'de>>(d: D) -> Result<Option<i64>, D::Error> {
114 struct V;
115 impl<'de> Visitor<'de> for V {
116 type Value = Option<i64>;
117 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
118 f.write_str("null, i64, or string-encoded i64")
119 }
120 fn visit_unit<E: de::Error>(self) -> Result<Option<i64>, E> {
121 Ok(None)
122 }
123 fn visit_none<E: de::Error>(self) -> Result<Option<i64>, E> {
124 Ok(None)
125 }
126 fn visit_some<D2: Deserializer<'de>>(self, d: D2) -> Result<Option<i64>, D2::Error> {
127 deserialize_i64(d).map(Some)
128 }
129 }
130 d.deserialize_option(V)
131}
132
133pub fn deserialize_option_option_u64<'de, D: Deserializer<'de>>(
146 d: D,
147) -> Result<Option<Option<u64>>, D::Error> {
148 struct V;
149 impl<'de> Visitor<'de> for V {
150 type Value = Option<Option<u64>>;
151 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
152 f.write_str("null, u64, or string-encoded u64")
153 }
154 fn visit_unit<E: de::Error>(self) -> Result<Option<Option<u64>>, E> {
155 Ok(Some(None))
156 }
157 fn visit_u64<E: de::Error>(self, v: u64) -> Result<Option<Option<u64>>, E> {
158 Ok(Some(Some(v)))
159 }
160 fn visit_i64<E: de::Error>(self, v: i64) -> Result<Option<Option<u64>>, E> {
161 u64::try_from(v)
162 .map(|v| Some(Some(v)))
163 .map_err(|_| E::custom(format!("negative value {v} cannot be u64")))
164 }
165 fn visit_f64<E: de::Error>(self, v: f64) -> Result<Option<Option<u64>>, E> {
166 if v >= 0.0 && v < (u64::MAX as f64) {
167 Ok(Some(Some(v as u64)))
168 } else {
169 Err(E::custom(format!("f64 {v} out of u64 range")))
170 }
171 }
172 fn visit_str<E: de::Error>(self, v: &str) -> Result<Option<Option<u64>>, E> {
173 v.parse().map(|v| Some(Some(v))).map_err(E::custom)
174 }
175 }
176 d.deserialize_any(V)
177}
178
179pub fn deserialize_option_option_i64<'de, D: Deserializer<'de>>(
181 d: D,
182) -> Result<Option<Option<i64>>, D::Error> {
183 struct V;
184 impl<'de> Visitor<'de> for V {
185 type Value = Option<Option<i64>>;
186 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
187 f.write_str("null, i64, or string-encoded i64")
188 }
189 fn visit_unit<E: de::Error>(self) -> Result<Option<Option<i64>>, E> {
190 Ok(Some(None))
191 }
192 fn visit_u64<E: de::Error>(self, v: u64) -> Result<Option<Option<i64>>, E> {
193 i64::try_from(v)
194 .map(|v| Some(Some(v)))
195 .map_err(|_| E::custom(format!("u64 {v} overflows i64")))
196 }
197 fn visit_i64<E: de::Error>(self, v: i64) -> Result<Option<Option<i64>>, E> {
198 Ok(Some(Some(v)))
199 }
200 fn visit_f64<E: de::Error>(self, v: f64) -> Result<Option<Option<i64>>, E> {
201 Ok(Some(Some(v as i64)))
202 }
203 fn visit_str<E: de::Error>(self, v: &str) -> Result<Option<Option<i64>>, E> {
204 v.parse().map(|v| Some(Some(v))).map_err(E::custom)
205 }
206 }
207 d.deserialize_any(V)
208}
209
210pub fn deserialize_option_vec_u64<'de, D: Deserializer<'de>>(
215 d: D,
216) -> Result<Option<Vec<u64>>, D::Error> {
217 struct V;
218 impl<'de> Visitor<'de> for V {
219 type Value = Option<Vec<u64>>;
220 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
221 f.write_str("null or array of u64/string-encoded u64")
222 }
223 fn visit_unit<E: de::Error>(self) -> Result<Option<Vec<u64>>, E> {
224 Ok(None)
225 }
226 fn visit_none<E: de::Error>(self) -> Result<Option<Vec<u64>>, E> {
227 Ok(None)
228 }
229 fn visit_some<D2: Deserializer<'de>>(self, d: D2) -> Result<Option<Vec<u64>>, D2::Error> {
230 struct SeqV;
231 impl<'de> Visitor<'de> for SeqV {
232 type Value = Vec<u64>;
233 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
234 f.write_str("array of u64/string-encoded u64")
235 }
236 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Vec<u64>, A::Error> {
237 let mut vec = Vec::with_capacity(seq.size_hint().unwrap_or(0));
238 while let Some(elem) = seq.next_element::<serde_json::Value>()? {
239 let n = match &elem {
240 serde_json::Value::Number(n) => n
241 .as_u64()
242 .or_else(|| n.as_i64().and_then(|i| u64::try_from(i).ok()))
243 .ok_or_else(|| {
244 de::Error::custom(format!("cannot convert {n} to u64"))
245 })?,
246 serde_json::Value::String(s) => {
247 s.parse::<u64>().map_err(de::Error::custom)?
248 }
249 other => {
250 return Err(de::Error::custom(format!(
251 "expected number or string in array, got {other}"
252 )));
253 }
254 };
255 vec.push(n);
256 }
257 Ok(vec)
258 }
259 }
260 d.deserialize_seq(SeqV).map(Some)
261 }
262 }
263 d.deserialize_option(V)
264}
265
266pub fn deserialize_option_option_vec_u64<'de, D: Deserializer<'de>>(
268 d: D,
269) -> Result<Option<Option<Vec<u64>>>, D::Error> {
270 struct V;
271 impl<'de> Visitor<'de> for V {
272 type Value = Option<Option<Vec<u64>>>;
273 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
274 f.write_str("null or array of u64/string-encoded u64")
275 }
276 fn visit_unit<E: de::Error>(self) -> Result<Option<Option<Vec<u64>>>, E> {
277 Ok(Some(None))
278 }
279 fn visit_seq<A: SeqAccess<'de>>(
280 self,
281 mut seq: A,
282 ) -> Result<Option<Option<Vec<u64>>>, A::Error> {
283 let mut vec = Vec::with_capacity(seq.size_hint().unwrap_or(0));
284 while let Some(elem) = seq.next_element::<serde_json::Value>()? {
285 let n = match &elem {
286 serde_json::Value::Number(n) => n
287 .as_u64()
288 .or_else(|| n.as_i64().and_then(|i| u64::try_from(i).ok()))
289 .ok_or_else(|| de::Error::custom(format!("cannot convert {n} to u64")))?,
290 serde_json::Value::String(s) => s.parse::<u64>().map_err(de::Error::custom)?,
291 other => {
292 return Err(de::Error::custom(format!(
293 "expected number or string in array, got {other}"
294 )));
295 }
296 };
297 vec.push(n);
298 }
299 Ok(Some(Some(vec)))
300 }
301 }
302 d.deserialize_any(V)
303}
304
305pub fn deserialize_option_vec_i64<'de, D: Deserializer<'de>>(
307 d: D,
308) -> Result<Option<Vec<i64>>, D::Error> {
309 struct V;
310 impl<'de> Visitor<'de> for V {
311 type Value = Option<Vec<i64>>;
312 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
313 f.write_str("null or array of i64/string-encoded i64")
314 }
315 fn visit_unit<E: de::Error>(self) -> Result<Option<Vec<i64>>, E> {
316 Ok(None)
317 }
318 fn visit_none<E: de::Error>(self) -> Result<Option<Vec<i64>>, E> {
319 Ok(None)
320 }
321 fn visit_some<D2: Deserializer<'de>>(self, d: D2) -> Result<Option<Vec<i64>>, D2::Error> {
322 struct SeqV;
323 impl<'de> Visitor<'de> for SeqV {
324 type Value = Vec<i64>;
325 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
326 f.write_str("array of i64/string-encoded i64")
327 }
328 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Vec<i64>, A::Error> {
329 let mut vec = Vec::with_capacity(seq.size_hint().unwrap_or(0));
330 while let Some(elem) = seq.next_element::<serde_json::Value>()? {
331 let n = match &elem {
332 serde_json::Value::Number(n) => n.as_i64().ok_or_else(|| {
333 de::Error::custom(format!("cannot convert {n} to i64"))
334 })?,
335 serde_json::Value::String(s) => {
336 s.parse::<i64>().map_err(de::Error::custom)?
337 }
338 other => {
339 return Err(de::Error::custom(format!(
340 "expected number or string in array, got {other}"
341 )));
342 }
343 };
344 vec.push(n);
345 }
346 Ok(vec)
347 }
348 }
349 d.deserialize_seq(SeqV).map(Some)
350 }
351 }
352 d.deserialize_option(V)
353}
354
355pub fn deserialize_option_option_vec_i64<'de, D: Deserializer<'de>>(
357 d: D,
358) -> Result<Option<Option<Vec<i64>>>, D::Error> {
359 struct V;
360 impl<'de> Visitor<'de> for V {
361 type Value = Option<Option<Vec<i64>>>;
362 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
363 f.write_str("null or array of i64/string-encoded i64")
364 }
365 fn visit_unit<E: de::Error>(self) -> Result<Option<Option<Vec<i64>>>, E> {
366 Ok(Some(None))
367 }
368 fn visit_seq<A: SeqAccess<'de>>(
369 self,
370 mut seq: A,
371 ) -> Result<Option<Option<Vec<i64>>>, A::Error> {
372 let mut vec = Vec::with_capacity(seq.size_hint().unwrap_or(0));
373 while let Some(elem) = seq.next_element::<serde_json::Value>()? {
374 let n = match &elem {
375 serde_json::Value::Number(n) => n
376 .as_i64()
377 .ok_or_else(|| de::Error::custom(format!("cannot convert {n} to i64")))?,
378 serde_json::Value::String(s) => s.parse::<i64>().map_err(de::Error::custom)?,
379 other => {
380 return Err(de::Error::custom(format!(
381 "expected number or string in array, got {other}"
382 )));
383 }
384 };
385 vec.push(n);
386 }
387 Ok(Some(Some(vec)))
388 }
389 }
390 d.deserialize_any(V)
391}
392
393fn narrow_opt<W, N, E: de::Error>(opt: Option<W>) -> Result<Option<N>, E>
398where
399 N: TryFrom<W>,
400 N::Error: fmt::Display,
401{
402 opt.map(|v| N::try_from(v).map_err(E::custom)).transpose()
403}
404
405fn narrow_opt_opt<W, N, E: de::Error>(opt: Option<Option<W>>) -> Result<Option<Option<N>>, E>
406where
407 N: TryFrom<W>,
408 N::Error: fmt::Display,
409{
410 match opt {
411 None => Ok(None),
412 Some(None) => Ok(Some(None)),
413 Some(Some(v)) => N::try_from(v).map(|n| Some(Some(n))).map_err(E::custom),
414 }
415}
416
417fn narrow_opt_vec<W, N, E: de::Error>(opt: Option<Vec<W>>) -> Result<Option<Vec<N>>, E>
418where
419 N: TryFrom<W>,
420 N::Error: fmt::Display,
421{
422 opt.map(|vec| {
423 vec.into_iter()
424 .map(|v| N::try_from(v).map_err(E::custom))
425 .collect()
426 })
427 .transpose()
428}
429
430fn narrow_opt_opt_vec<W, N, E: de::Error>(
431 opt: Option<Option<Vec<W>>>,
432) -> Result<Option<Option<Vec<N>>>, E>
433where
434 N: TryFrom<W>,
435 N::Error: fmt::Display,
436{
437 match opt {
438 None => Ok(None),
439 Some(None) => Ok(Some(None)),
440 Some(Some(vec)) => vec
441 .into_iter()
442 .map(|v| N::try_from(v).map_err(E::custom))
443 .collect::<Result<Vec<N>, E>>()
444 .map(|v| Some(Some(v))),
445 }
446}
447
448pub fn deserialize_option_u32<'de, D: Deserializer<'de>>(d: D) -> Result<Option<u32>, D::Error> {
451 narrow_opt(deserialize_option_u64(d)?)
452}
453
454pub fn deserialize_option_i32<'de, D: Deserializer<'de>>(d: D) -> Result<Option<i32>, D::Error> {
455 narrow_opt(deserialize_option_i64(d)?)
456}
457
458pub fn deserialize_option_option_u32<'de, D: Deserializer<'de>>(
461 d: D,
462) -> Result<Option<Option<u32>>, D::Error> {
463 narrow_opt_opt(deserialize_option_option_u64(d)?)
464}
465
466pub fn deserialize_option_option_i32<'de, D: Deserializer<'de>>(
467 d: D,
468) -> Result<Option<Option<i32>>, D::Error> {
469 narrow_opt_opt(deserialize_option_option_i64(d)?)
470}
471
472pub fn deserialize_option_vec_u32<'de, D: Deserializer<'de>>(
475 d: D,
476) -> Result<Option<Vec<u32>>, D::Error> {
477 narrow_opt_vec(deserialize_option_vec_u64(d)?)
478}
479
480pub fn deserialize_option_vec_i32<'de, D: Deserializer<'de>>(
481 d: D,
482) -> Result<Option<Vec<i32>>, D::Error> {
483 narrow_opt_vec(deserialize_option_vec_i64(d)?)
484}
485
486pub fn deserialize_option_option_vec_u32<'de, D: Deserializer<'de>>(
489 d: D,
490) -> Result<Option<Option<Vec<u32>>>, D::Error> {
491 narrow_opt_opt_vec(deserialize_option_option_vec_u64(d)?)
492}
493
494pub fn deserialize_option_option_vec_i32<'de, D: Deserializer<'de>>(
495 d: D,
496) -> Result<Option<Option<Vec<i32>>>, D::Error> {
497 narrow_opt_opt_vec(deserialize_option_option_vec_i64(d)?)
498}
499
500#[cfg(test)]
501mod tests {
502 use super::*;
503 use serde::Deserialize;
504
505 #[derive(Deserialize, Debug, PartialEq)]
506 struct TestBare {
507 #[serde(deserialize_with = "deserialize_u64")]
508 balance: u64,
509 #[serde(deserialize_with = "deserialize_i64")]
510 timestamp: i64,
511 }
512
513 #[derive(Deserialize, Debug, PartialEq)]
514 struct TestOption {
515 #[serde(default, deserialize_with = "deserialize_option_u64")]
516 balance: Option<u64>,
517 #[serde(default, deserialize_with = "deserialize_option_i64")]
518 timestamp: Option<i64>,
519 }
520
521 #[derive(Deserialize, Debug, PartialEq)]
522 struct TestOptionOption {
523 #[serde(default, deserialize_with = "deserialize_option_option_u64")]
524 balance: Option<Option<u64>>,
525 #[serde(default, deserialize_with = "deserialize_option_option_i64")]
526 timestamp: Option<Option<i64>>,
527 }
528
529 #[derive(Deserialize, Debug, PartialEq)]
530 struct TestVec {
531 #[serde(default, deserialize_with = "deserialize_option_vec_u64")]
532 values: Option<Vec<u64>>,
533 }
534
535 #[derive(Deserialize, Debug, PartialEq)]
536 struct TestOptionOptionVec {
537 #[serde(default, deserialize_with = "deserialize_option_option_vec_u64")]
538 values: Option<Option<Vec<u64>>>,
539 }
540
541 #[derive(Deserialize, Debug, PartialEq)]
542 struct TestVecI64 {
543 #[serde(default, deserialize_with = "deserialize_option_vec_i64")]
544 values: Option<Vec<i64>>,
545 }
546
547 #[derive(Deserialize, Debug, PartialEq)]
548 struct TestOptionOptionVecI64 {
549 #[serde(default, deserialize_with = "deserialize_option_option_vec_i64")]
550 values: Option<Option<Vec<i64>>>,
551 }
552
553 #[test]
556 fn bare_u64_from_number() {
557 let v: TestBare = serde_json::from_str(r#"{"balance": 42, "timestamp": -100}"#).unwrap();
558 assert_eq!(v.balance, 42);
559 assert_eq!(v.timestamp, -100);
560 }
561
562 #[test]
563 fn bare_u64_from_string() {
564 let v: TestBare =
565 serde_json::from_str(r#"{"balance": "9007199254740992", "timestamp": "-100"}"#)
566 .unwrap();
567 assert_eq!(v.balance, 9007199254740992);
568 assert_eq!(v.timestamp, -100);
569 }
570
571 #[test]
574 fn option_from_number() {
575 let v: TestOption = serde_json::from_str(r#"{"balance": 42, "timestamp": -100}"#).unwrap();
576 assert_eq!(v.balance, Some(42));
577 assert_eq!(v.timestamp, Some(-100));
578 }
579
580 #[test]
581 fn option_from_string() {
582 let v: TestOption =
583 serde_json::from_str(r#"{"balance": "9007199254740992", "timestamp": "123"}"#).unwrap();
584 assert_eq!(v.balance, Some(9007199254740992));
585 assert_eq!(v.timestamp, Some(123));
586 }
587
588 #[test]
589 fn option_from_null() {
590 let v: TestOption =
591 serde_json::from_str(r#"{"balance": null, "timestamp": null}"#).unwrap();
592 assert_eq!(v.balance, None);
593 assert_eq!(v.timestamp, None);
594 }
595
596 #[test]
597 fn option_missing_field() {
598 let v: TestOption = serde_json::from_str(r#"{}"#).unwrap();
599 assert_eq!(v.balance, None);
600 assert_eq!(v.timestamp, None);
601 }
602
603 #[test]
606 fn option_option_from_number() {
607 let v: TestOptionOption =
608 serde_json::from_str(r#"{"balance": 42, "timestamp": -100}"#).unwrap();
609 assert_eq!(v.balance, Some(Some(42)));
610 assert_eq!(v.timestamp, Some(Some(-100)));
611 }
612
613 #[test]
614 fn option_option_from_string() {
615 let v: TestOptionOption =
616 serde_json::from_str(r#"{"balance": "9007199254740992", "timestamp": "123"}"#).unwrap();
617 assert_eq!(v.balance, Some(Some(9007199254740992)));
618 assert_eq!(v.timestamp, Some(Some(123)));
619 }
620
621 #[test]
622 fn option_option_null_means_explicit_null() {
623 let v: TestOptionOption =
624 serde_json::from_str(r#"{"balance": null, "timestamp": null}"#).unwrap();
625 assert_eq!(v.balance, Some(None)); assert_eq!(v.timestamp, Some(None));
627 }
628
629 #[test]
630 fn option_option_missing_means_not_received() {
631 let v: TestOptionOption = serde_json::from_str(r#"{}"#).unwrap();
632 assert_eq!(v.balance, None); assert_eq!(v.timestamp, None);
634 }
635
636 #[test]
639 fn vec_mixed_numbers_and_strings() {
640 let v: TestVec = serde_json::from_str(r#"{"values": [1, "9007199254740992", 3]}"#).unwrap();
641 assert_eq!(v.values, Some(vec![1, 9007199254740992, 3]));
642 }
643
644 #[test]
645 fn vec_null() {
646 let v: TestVec = serde_json::from_str(r#"{"values": null}"#).unwrap();
647 assert_eq!(v.values, None);
648 }
649
650 #[test]
651 fn vec_missing() {
652 let v: TestVec = serde_json::from_str(r#"{}"#).unwrap();
653 assert_eq!(v.values, None);
654 }
655
656 #[test]
657 fn option_option_vec_from_array() {
658 let v: TestOptionOptionVec =
659 serde_json::from_str(r#"{"values": [1, "9007199254740992"]}"#).unwrap();
660 assert_eq!(v.values, Some(Some(vec![1, 9007199254740992])));
661 }
662
663 #[test]
664 fn option_option_vec_null() {
665 let v: TestOptionOptionVec = serde_json::from_str(r#"{"values": null}"#).unwrap();
666 assert_eq!(v.values, Some(None));
667 }
668
669 #[test]
670 fn option_option_vec_missing() {
671 let v: TestOptionOptionVec = serde_json::from_str(r#"{}"#).unwrap();
672 assert_eq!(v.values, None);
673 }
674
675 #[test]
678 fn vec_i64_mixed_numbers_and_strings() {
679 let v: TestVecI64 =
680 serde_json::from_str(r#"{"values": [-1, "9007199254740992", 3]}"#).unwrap();
681 assert_eq!(v.values, Some(vec![-1, 9007199254740992, 3]));
682 }
683
684 #[test]
685 fn vec_i64_null() {
686 let v: TestVecI64 = serde_json::from_str(r#"{"values": null}"#).unwrap();
687 assert_eq!(v.values, None);
688 }
689
690 #[test]
691 fn vec_i64_missing() {
692 let v: TestVecI64 = serde_json::from_str(r#"{}"#).unwrap();
693 assert_eq!(v.values, None);
694 }
695
696 #[test]
697 fn option_option_vec_i64_from_array() {
698 let v: TestOptionOptionVecI64 =
699 serde_json::from_str(r#"{"values": [-1, "9007199254740992"]}"#).unwrap();
700 assert_eq!(v.values, Some(Some(vec![-1, 9007199254740992])));
701 }
702
703 #[test]
704 fn option_option_vec_i64_null() {
705 let v: TestOptionOptionVecI64 = serde_json::from_str(r#"{"values": null}"#).unwrap();
706 assert_eq!(v.values, Some(None));
707 }
708
709 #[test]
710 fn option_option_vec_i64_missing() {
711 let v: TestOptionOptionVecI64 = serde_json::from_str(r#"{}"#).unwrap();
712 assert_eq!(v.values, None);
713 }
714
715 #[test]
718 fn large_u64_from_string() {
719 let v: TestOption = serde_json::from_str(r#"{"balance": "18446744073709551615"}"#).unwrap();
720 assert_eq!(v.balance, Some(u64::MAX));
721 }
722
723 #[test]
724 fn u64_from_float() {
725 let v: TestOption = serde_json::from_str(r#"{"balance": 42.0}"#).unwrap();
726 assert_eq!(v.balance, Some(42));
727 }
728
729 #[derive(Deserialize, Debug, PartialEq)]
732 struct TestOption32 {
733 #[serde(default, deserialize_with = "deserialize_option_u32")]
734 balance: Option<u32>,
735 #[serde(default, deserialize_with = "deserialize_option_i32")]
736 timestamp: Option<i32>,
737 }
738
739 #[test]
740 fn option_u32_from_number() {
741 let v: TestOption32 =
742 serde_json::from_str(r#"{"balance": 42, "timestamp": -100}"#).unwrap();
743 assert_eq!(v.balance, Some(42));
744 assert_eq!(v.timestamp, Some(-100));
745 }
746
747 #[test]
748 fn option_u32_from_string() {
749 let v: TestOption32 =
750 serde_json::from_str(r#"{"balance": "1000", "timestamp": "-50"}"#).unwrap();
751 assert_eq!(v.balance, Some(1000));
752 assert_eq!(v.timestamp, Some(-50));
753 }
754
755 #[test]
756 fn option_u32_overflow_rejected() {
757 let r = serde_json::from_str::<TestOption32>(r#"{"balance": 4294967296}"#);
758 assert!(r.is_err(), "u32 overflow should be rejected");
759 }
760
761 #[test]
762 fn option_i32_overflow_rejected() {
763 let r = serde_json::from_str::<TestOption32>(r#"{"timestamp": 2147483648}"#);
764 assert!(r.is_err(), "i32 overflow should be rejected");
765 }
766
767 #[test]
768 fn option_u32_null_and_missing() {
769 let v: TestOption32 =
770 serde_json::from_str(r#"{"balance": null, "timestamp": null}"#).unwrap();
771 assert_eq!(v.balance, None);
772 assert_eq!(v.timestamp, None);
773 let v: TestOption32 = serde_json::from_str(r#"{}"#).unwrap();
774 assert_eq!(v.balance, None);
775 assert_eq!(v.timestamp, None);
776 }
777
778 #[derive(Deserialize, Debug, PartialEq)]
779 struct TestOptionOption32 {
780 #[serde(default, deserialize_with = "deserialize_option_option_u32")]
781 balance: Option<Option<u32>>,
782 }
783
784 #[test]
785 fn option_option_u32_patch_semantics() {
786 let v: TestOptionOption32 = serde_json::from_str(r#"{"balance": 42}"#).unwrap();
787 assert_eq!(v.balance, Some(Some(42)));
788 let v: TestOptionOption32 = serde_json::from_str(r#"{"balance": null}"#).unwrap();
789 assert_eq!(v.balance, Some(None));
790 let v: TestOptionOption32 = serde_json::from_str(r#"{}"#).unwrap();
791 assert_eq!(v.balance, None);
792 }
793
794 #[derive(Deserialize, Debug, PartialEq)]
795 struct TestVec32 {
796 #[serde(default, deserialize_with = "deserialize_option_vec_u32")]
797 values: Option<Vec<u32>>,
798 }
799
800 #[test]
801 fn vec_u32_mixed() {
802 let v: TestVec32 = serde_json::from_str(r#"{"values": [1, "2", 3]}"#).unwrap();
803 assert_eq!(v.values, Some(vec![1, 2, 3]));
804 }
805
806 #[test]
807 fn vec_u32_overflow_rejected() {
808 let r = serde_json::from_str::<TestVec32>(r#"{"values": [1, 4294967296]}"#);
809 assert!(r.is_err());
810 }
811}