1use crate::de::ParserNumber;
2use crate::error::Error;
3#[cfg(feature = "arbitrary_precision")]
4use crate::error::ErrorCode;
5#[cfg(feature = "arbitrary_precision")]
6use alloc::borrow::ToOwned;
7#[cfg(feature = "arbitrary_precision")]
8use alloc::string::{String, ToString};
9use core::fmt::{self, Debug, Display};
10#[cfg(not(feature = "arbitrary_precision"))]
11use core::hash::{Hash, Hasher};
12use serde::de::{self, Unexpected, Visitor};
13#[cfg(feature = "arbitrary_precision")]
14use serde::de::{IntoDeserializer, MapAccess};
15use serde::{forward_to_deserialize_any, Deserialize, Deserializer, Serialize, Serializer};
16
17#[cfg(feature = "arbitrary_precision")]
18pub(crate) const TOKEN: &str = "$serde_json::private::Number";
19
20#[derive(Clone, PartialEq, Eq, Hash)]
22pub struct Number {
23 n: N,
24}
25
26#[cfg(not(feature = "arbitrary_precision"))]
27#[derive(Copy, Clone)]
28enum N {
29 PosInt(u64),
30 NegInt(i64),
32 Float(f64),
34}
35
36#[cfg(not(feature = "arbitrary_precision"))]
37impl PartialEq for N {
38 fn eq(&self, other: &Self) -> bool {
39 match (self, other) {
40 (N::PosInt(a), N::PosInt(b)) => a == b,
41 (N::NegInt(a), N::NegInt(b)) => a == b,
42 (N::Float(a), N::Float(b)) => a == b,
43 _ => false,
44 }
45 }
46}
47
48#[cfg(not(feature = "arbitrary_precision"))]
50impl Eq for N {}
51
52#[cfg(not(feature = "arbitrary_precision"))]
53impl Hash for N {
54 fn hash<H: Hasher>(&self, h: &mut H) {
55 match *self {
56 N::PosInt(i) => i.hash(h),
57 N::NegInt(i) => i.hash(h),
58 N::Float(f) => {
59 if f == 0.0f64 {
60 0.0f64.to_bits().hash(h);
64 } else {
65 f.to_bits().hash(h);
66 }
67 }
68 }
69 }
70}
71
72#[cfg(feature = "arbitrary_precision")]
73type N = String;
74
75impl Number {
76 pub fn is_i64(&self) -> bool {
82 #[cfg(not(feature = "arbitrary_precision"))]
83 match self.n {
84 N::PosInt(v) => v <= i64::MAX as u64,
85 N::NegInt(_) => true,
86 N::Float(_) => false,
87 }
88 #[cfg(feature = "arbitrary_precision")]
89 self.as_i64().is_some()
90 }
91
92 pub fn is_u64(&self) -> bool {
97 #[cfg(not(feature = "arbitrary_precision"))]
98 match self.n {
99 N::PosInt(_) => true,
100 N::NegInt(_) | N::Float(_) => false,
101 }
102 #[cfg(feature = "arbitrary_precision")]
103 self.as_u64().is_some()
104 }
105
106 pub fn is_f64(&self) -> bool {
114 #[cfg(not(feature = "arbitrary_precision"))]
115 match self.n {
116 N::Float(_) => true,
117 N::PosInt(_) | N::NegInt(_) => false,
118 }
119 #[cfg(feature = "arbitrary_precision")]
120 {
121 for c in self.n.chars() {
122 if c == '.' || c == 'e' || c == 'E' {
123 return self.n.parse::<f64>().ok().map_or(false, f64::is_finite);
124 }
125 }
126 false
127 }
128 }
129
130 pub fn as_i64(&self) -> Option<i64> {
133 #[cfg(not(feature = "arbitrary_precision"))]
134 match self.n {
135 N::PosInt(n) => {
136 if n <= i64::MAX as u64 {
137 Some(n as i64)
138 } else {
139 None
140 }
141 }
142 N::NegInt(n) => Some(n),
143 N::Float(_) => None,
144 }
145 #[cfg(feature = "arbitrary_precision")]
146 self.n.parse().ok()
147 }
148
149 pub fn as_u64(&self) -> Option<u64> {
152 #[cfg(not(feature = "arbitrary_precision"))]
153 match self.n {
154 N::PosInt(n) => Some(n),
155 N::NegInt(_) | N::Float(_) => None,
156 }
157 #[cfg(feature = "arbitrary_precision")]
158 self.n.parse().ok()
159 }
160
161 pub fn as_f64(&self) -> Option<f64> {
163 #[cfg(not(feature = "arbitrary_precision"))]
164 match self.n {
165 N::PosInt(n) => Some(n as f64),
166 N::NegInt(n) => Some(n as f64),
167 N::Float(n) => Some(n),
168 }
169 #[cfg(feature = "arbitrary_precision")]
170 self.n.parse::<f64>().ok().filter(|float| float.is_finite())
171 }
172
173 pub fn from_f64(f: f64) -> Option<Number> {
184 if f.is_finite() {
185 let n = {
186 #[cfg(not(feature = "arbitrary_precision"))]
187 {
188 N::Float(f)
189 }
190 #[cfg(feature = "arbitrary_precision")]
191 {
192 ryu::Buffer::new().format_finite(f).to_owned()
193 }
194 };
195 Some(Number { n })
196 } else {
197 None
198 }
199 }
200
201 pub fn as_i128(&self) -> Option<i128> {
204 #[cfg(not(feature = "arbitrary_precision"))]
205 match self.n {
206 N::PosInt(n) => Some(n as i128),
207 N::NegInt(n) => Some(n as i128),
208 N::Float(_) => None,
209 }
210 #[cfg(feature = "arbitrary_precision")]
211 self.n.parse().ok()
212 }
213
214 pub fn as_u128(&self) -> Option<u128> {
217 #[cfg(not(feature = "arbitrary_precision"))]
218 match self.n {
219 N::PosInt(n) => Some(n as u128),
220 N::NegInt(_) | N::Float(_) => None,
221 }
222 #[cfg(feature = "arbitrary_precision")]
223 self.n.parse().ok()
224 }
225
226 pub fn from_i128(i: i128) -> Option<Number> {
236 let n = {
237 #[cfg(not(feature = "arbitrary_precision"))]
238 {
239 if let Ok(u) = u64::try_from(i) {
240 N::PosInt(u)
241 } else if let Ok(i) = i64::try_from(i) {
242 N::NegInt(i)
243 } else {
244 return None;
245 }
246 }
247 #[cfg(feature = "arbitrary_precision")]
248 {
249 i.to_string()
250 }
251 };
252 Some(Number { n })
253 }
254
255 pub fn from_u128(i: u128) -> Option<Number> {
265 let n = {
266 #[cfg(not(feature = "arbitrary_precision"))]
267 {
268 if let Ok(u) = u64::try_from(i) {
269 N::PosInt(u)
270 } else {
271 return None;
272 }
273 }
274 #[cfg(feature = "arbitrary_precision")]
275 {
276 i.to_string()
277 }
278 };
279 Some(Number { n })
280 }
281
282 #[cfg(feature = "arbitrary_precision")]
304 #[cfg_attr(docsrs, doc(cfg(feature = "arbitrary_precision")))]
305 pub fn as_str(&self) -> &str {
306 &self.n
307 }
308
309 pub(crate) fn as_f32(&self) -> Option<f32> {
310 #[cfg(not(feature = "arbitrary_precision"))]
311 match self.n {
312 N::PosInt(n) => Some(n as f32),
313 N::NegInt(n) => Some(n as f32),
314 N::Float(n) => Some(n as f32),
315 }
316 #[cfg(feature = "arbitrary_precision")]
317 self.n.parse::<f32>().ok().filter(|float| float.is_finite())
318 }
319
320 pub(crate) fn from_f32(f: f32) -> Option<Number> {
321 if f.is_finite() {
322 let n = {
323 #[cfg(not(feature = "arbitrary_precision"))]
324 {
325 N::Float(f as f64)
326 }
327 #[cfg(feature = "arbitrary_precision")]
328 {
329 ryu::Buffer::new().format_finite(f).to_owned()
330 }
331 };
332 Some(Number { n })
333 } else {
334 None
335 }
336 }
337
338 #[cfg(feature = "arbitrary_precision")]
339 #[doc(hidden)]
341 #[inline]
342 pub fn from_string_unchecked(n: String) -> Self {
343 Number { n }
344 }
345}
346
347impl Display for Number {
348 #[cfg(not(feature = "arbitrary_precision"))]
349 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
350 match self.n {
351 N::PosInt(u) => formatter.write_str(itoa::Buffer::new().format(u)),
352 N::NegInt(i) => formatter.write_str(itoa::Buffer::new().format(i)),
353 N::Float(f) => formatter.write_str(ryu::Buffer::new().format_finite(f)),
354 }
355 }
356
357 #[cfg(feature = "arbitrary_precision")]
358 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
359 Display::fmt(&self.n, formatter)
360 }
361}
362
363impl Debug for Number {
364 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
365 write!(formatter, "Number({})", self)
366 }
367}
368
369impl Serialize for Number {
370 #[cfg(not(feature = "arbitrary_precision"))]
371 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
372 where
373 S: Serializer,
374 {
375 match self.n {
376 N::PosInt(u) => serializer.serialize_u64(u),
377 N::NegInt(i) => serializer.serialize_i64(i),
378 N::Float(f) => serializer.serialize_f64(f),
379 }
380 }
381
382 #[cfg(feature = "arbitrary_precision")]
383 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
384 where
385 S: Serializer,
386 {
387 use serde::ser::SerializeStruct;
388
389 let mut s = tri!(serializer.serialize_struct(TOKEN, 1));
390 tri!(s.serialize_field(TOKEN, &self.n));
391 s.end()
392 }
393}
394
395impl<'de> Deserialize<'de> for Number {
396 #[inline]
397 fn deserialize<D>(deserializer: D) -> Result<Number, D::Error>
398 where
399 D: Deserializer<'de>,
400 {
401 struct NumberVisitor;
402
403 impl<'de> Visitor<'de> for NumberVisitor {
404 type Value = Number;
405
406 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
407 formatter.write_str("a JSON number")
408 }
409
410 fn visit_i64<E>(self, value: i64) -> Result<Number, E> {
411 Ok(value.into())
412 }
413
414 fn visit_i128<E>(self, value: i128) -> Result<Number, E>
415 where
416 E: de::Error,
417 {
418 Number::from_i128(value)
419 .ok_or_else(|| de::Error::custom("JSON number out of range"))
420 }
421
422 fn visit_u64<E>(self, value: u64) -> Result<Number, E> {
423 Ok(value.into())
424 }
425
426 fn visit_u128<E>(self, value: u128) -> Result<Number, E>
427 where
428 E: de::Error,
429 {
430 Number::from_u128(value)
431 .ok_or_else(|| de::Error::custom("JSON number out of range"))
432 }
433
434 fn visit_f64<E>(self, value: f64) -> Result<Number, E>
435 where
436 E: de::Error,
437 {
438 Number::from_f64(value).ok_or_else(|| de::Error::custom("not a JSON number"))
439 }
440
441 #[cfg(feature = "arbitrary_precision")]
442 fn visit_map<V>(self, mut visitor: V) -> Result<Number, V::Error>
443 where
444 V: de::MapAccess<'de>,
445 {
446 let value = tri!(visitor.next_key::<NumberKey>());
447 if value.is_none() {
448 return Err(de::Error::invalid_type(Unexpected::Map, &self));
449 }
450 let v: NumberFromString = tri!(visitor.next_value());
451 Ok(v.value)
452 }
453 }
454
455 deserializer.deserialize_any(NumberVisitor)
456 }
457}
458
459#[cfg(feature = "arbitrary_precision")]
460struct NumberKey;
461
462#[cfg(feature = "arbitrary_precision")]
463impl<'de> de::Deserialize<'de> for NumberKey {
464 fn deserialize<D>(deserializer: D) -> Result<NumberKey, D::Error>
465 where
466 D: de::Deserializer<'de>,
467 {
468 struct FieldVisitor;
469
470 impl<'de> de::Visitor<'de> for FieldVisitor {
471 type Value = ();
472
473 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
474 formatter.write_str("a valid number field")
475 }
476
477 fn visit_str<E>(self, s: &str) -> Result<(), E>
478 where
479 E: de::Error,
480 {
481 if s == TOKEN {
482 Ok(())
483 } else {
484 Err(de::Error::custom("expected field with custom name"))
485 }
486 }
487 }
488
489 tri!(deserializer.deserialize_identifier(FieldVisitor));
490 Ok(NumberKey)
491 }
492}
493
494#[cfg(feature = "arbitrary_precision")]
495pub struct NumberFromString {
496 pub value: Number,
497}
498
499#[cfg(feature = "arbitrary_precision")]
500impl<'de> de::Deserialize<'de> for NumberFromString {
501 fn deserialize<D>(deserializer: D) -> Result<NumberFromString, D::Error>
502 where
503 D: de::Deserializer<'de>,
504 {
505 struct Visitor;
506
507 impl<'de> de::Visitor<'de> for Visitor {
508 type Value = NumberFromString;
509
510 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
511 formatter.write_str("string containing a number")
512 }
513
514 fn visit_str<E>(self, s: &str) -> Result<NumberFromString, E>
515 where
516 E: de::Error,
517 {
518 let n = tri!(s.parse().map_err(de::Error::custom));
519 Ok(NumberFromString { value: n })
520 }
521 }
522
523 deserializer.deserialize_str(Visitor)
524 }
525}
526
527#[cfg(feature = "arbitrary_precision")]
528fn invalid_number() -> Error {
529 Error::syntax(ErrorCode::InvalidNumber, 0, 0)
530}
531
532macro_rules! deserialize_any {
533 (@expand [$($num_string:tt)*]) => {
534 #[cfg(not(feature = "arbitrary_precision"))]
535 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
536 where
537 V: Visitor<'de>,
538 {
539 match self.n {
540 N::PosInt(u) => visitor.visit_u64(u),
541 N::NegInt(i) => visitor.visit_i64(i),
542 N::Float(f) => visitor.visit_f64(f),
543 }
544 }
545
546 #[cfg(feature = "arbitrary_precision")]
547 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
548 where V: Visitor<'de>
549 {
550 if let Some(u) = self.as_u64() {
551 return visitor.visit_u64(u);
552 } else if let Some(i) = self.as_i64() {
553 return visitor.visit_i64(i);
554 } else if let Some(u) = self.as_u128() {
555 return visitor.visit_u128(u);
556 } else if let Some(i) = self.as_i128() {
557 return visitor.visit_i128(i);
558 } else if let Some(f) = self.as_f64() {
559 if ryu::Buffer::new().format_finite(f) == self.n || f.to_string() == self.n {
560 return visitor.visit_f64(f);
561 }
562 }
563
564 visitor.visit_map(NumberDeserializer {
565 number: Some(self.$($num_string)*),
566 })
567 }
568 };
569
570 (owned) => {
571 deserialize_any!(@expand [n]);
572 };
573
574 (ref) => {
575 deserialize_any!(@expand [n.clone()]);
576 };
577}
578
579macro_rules! deserialize_number {
580 ($deserialize:ident => $visit:ident) => {
581 #[cfg(not(feature = "arbitrary_precision"))]
582 fn $deserialize<V>(self, visitor: V) -> Result<V::Value, Error>
583 where
584 V: Visitor<'de>,
585 {
586 self.deserialize_any(visitor)
587 }
588
589 #[cfg(feature = "arbitrary_precision")]
590 fn $deserialize<V>(self, visitor: V) -> Result<V::Value, Error>
591 where
592 V: de::Visitor<'de>,
593 {
594 visitor.$visit(tri!(self.n.parse().map_err(|_| invalid_number())))
595 }
596 };
597}
598
599impl<'de> Deserializer<'de> for Number {
600 type Error = Error;
601
602 deserialize_any!(owned);
603
604 deserialize_number!(deserialize_i8 => visit_i8);
605 deserialize_number!(deserialize_i16 => visit_i16);
606 deserialize_number!(deserialize_i32 => visit_i32);
607 deserialize_number!(deserialize_i64 => visit_i64);
608 deserialize_number!(deserialize_i128 => visit_i128);
609 deserialize_number!(deserialize_u8 => visit_u8);
610 deserialize_number!(deserialize_u16 => visit_u16);
611 deserialize_number!(deserialize_u32 => visit_u32);
612 deserialize_number!(deserialize_u64 => visit_u64);
613 deserialize_number!(deserialize_u128 => visit_u128);
614 deserialize_number!(deserialize_f32 => visit_f32);
615 deserialize_number!(deserialize_f64 => visit_f64);
616
617 forward_to_deserialize_any! {
618 bool char str string bytes byte_buf option unit unit_struct
619 newtype_struct seq tuple tuple_struct map struct enum identifier
620 ignored_any
621 }
622}
623
624impl<'de> Deserializer<'de> for &Number {
625 type Error = Error;
626
627 deserialize_any!(ref);
628
629 deserialize_number!(deserialize_i8 => visit_i8);
630 deserialize_number!(deserialize_i16 => visit_i16);
631 deserialize_number!(deserialize_i32 => visit_i32);
632 deserialize_number!(deserialize_i64 => visit_i64);
633 deserialize_number!(deserialize_i128 => visit_i128);
634 deserialize_number!(deserialize_u8 => visit_u8);
635 deserialize_number!(deserialize_u16 => visit_u16);
636 deserialize_number!(deserialize_u32 => visit_u32);
637 deserialize_number!(deserialize_u64 => visit_u64);
638 deserialize_number!(deserialize_u128 => visit_u128);
639 deserialize_number!(deserialize_f32 => visit_f32);
640 deserialize_number!(deserialize_f64 => visit_f64);
641
642 forward_to_deserialize_any! {
643 bool char str string bytes byte_buf option unit unit_struct
644 newtype_struct seq tuple tuple_struct map struct enum identifier
645 ignored_any
646 }
647}
648
649#[cfg(feature = "arbitrary_precision")]
650pub(crate) struct NumberDeserializer {
651 pub number: Option<String>,
652}
653
654#[cfg(feature = "arbitrary_precision")]
655impl<'de> MapAccess<'de> for NumberDeserializer {
656 type Error = Error;
657
658 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
659 where
660 K: de::DeserializeSeed<'de>,
661 {
662 if self.number.is_none() {
663 return Ok(None);
664 }
665 seed.deserialize(NumberFieldDeserializer).map(Some)
666 }
667
668 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
669 where
670 V: de::DeserializeSeed<'de>,
671 {
672 seed.deserialize(self.number.take().unwrap().into_deserializer())
673 }
674}
675
676#[cfg(feature = "arbitrary_precision")]
677struct NumberFieldDeserializer;
678
679#[cfg(feature = "arbitrary_precision")]
680impl<'de> Deserializer<'de> for NumberFieldDeserializer {
681 type Error = Error;
682
683 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
684 where
685 V: de::Visitor<'de>,
686 {
687 visitor.visit_borrowed_str(TOKEN)
688 }
689
690 forward_to_deserialize_any! {
691 bool u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 char str string seq
692 bytes byte_buf map struct option unit newtype_struct ignored_any
693 unit_struct tuple_struct tuple enum identifier
694 }
695}
696
697impl From<ParserNumber> for Number {
698 fn from(value: ParserNumber) -> Self {
699 let n = match value {
700 ParserNumber::F64(f) => {
701 #[cfg(not(feature = "arbitrary_precision"))]
702 {
703 N::Float(f)
704 }
705 #[cfg(feature = "arbitrary_precision")]
706 {
707 ryu::Buffer::new().format_finite(f).to_owned()
708 }
709 }
710 ParserNumber::U64(u) => {
711 #[cfg(not(feature = "arbitrary_precision"))]
712 {
713 N::PosInt(u)
714 }
715 #[cfg(feature = "arbitrary_precision")]
716 {
717 itoa::Buffer::new().format(u).to_owned()
718 }
719 }
720 ParserNumber::I64(i) => {
721 #[cfg(not(feature = "arbitrary_precision"))]
722 {
723 N::NegInt(i)
724 }
725 #[cfg(feature = "arbitrary_precision")]
726 {
727 itoa::Buffer::new().format(i).to_owned()
728 }
729 }
730 #[cfg(feature = "arbitrary_precision")]
731 ParserNumber::String(s) => s,
732 };
733 Number { n }
734 }
735}
736
737macro_rules! impl_from_unsigned {
738 (
739 $($ty:ty),*
740 ) => {
741 $(
742 impl From<$ty> for Number {
743 fn from(u: $ty) -> Self {
744 let n = {
745 #[cfg(not(feature = "arbitrary_precision"))]
746 { N::PosInt(u as u64) }
747 #[cfg(feature = "arbitrary_precision")]
748 {
749 itoa::Buffer::new().format(u).to_owned()
750 }
751 };
752 Number { n }
753 }
754 }
755 )*
756 };
757}
758
759macro_rules! impl_from_signed {
760 (
761 $($ty:ty),*
762 ) => {
763 $(
764 impl From<$ty> for Number {
765 fn from(i: $ty) -> Self {
766 let n = {
767 #[cfg(not(feature = "arbitrary_precision"))]
768 {
769 if i < 0 {
770 N::NegInt(i as i64)
771 } else {
772 N::PosInt(i as u64)
773 }
774 }
775 #[cfg(feature = "arbitrary_precision")]
776 {
777 itoa::Buffer::new().format(i).to_owned()
778 }
779 };
780 Number { n }
781 }
782 }
783 )*
784 };
785}
786
787impl_from_unsigned!(u8, u16, u32, u64, usize);
788impl_from_signed!(i8, i16, i32, i64, isize);
789
790#[cfg(feature = "arbitrary_precision")]
791impl_from_unsigned!(u128);
792#[cfg(feature = "arbitrary_precision")]
793impl_from_signed!(i128);
794
795impl Number {
796 #[cfg(not(feature = "arbitrary_precision"))]
797 #[cold]
798 pub(crate) fn unexpected(&self) -> Unexpected {
799 match self.n {
800 N::PosInt(u) => Unexpected::Unsigned(u),
801 N::NegInt(i) => Unexpected::Signed(i),
802 N::Float(f) => Unexpected::Float(f),
803 }
804 }
805
806 #[cfg(feature = "arbitrary_precision")]
807 #[cold]
808 pub(crate) fn unexpected(&self) -> Unexpected {
809 Unexpected::Other("number")
810 }
811}