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 zmij::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")]
307 #[cfg_attr(docsrs, doc(cfg(feature = "arbitrary_precision")))]
308 pub fn as_str(&self) -> &str {
309 &self.n
310 }
311
312 pub(crate) fn as_f32(&self) -> Option<f32> {
313 #[cfg(not(feature = "arbitrary_precision"))]
314 match self.n {
315 N::PosInt(n) => Some(n as f32),
316 N::NegInt(n) => Some(n as f32),
317 N::Float(n) => Some(n as f32),
318 }
319 #[cfg(feature = "arbitrary_precision")]
320 self.n.parse::<f32>().ok().filter(|float| float.is_finite())
321 }
322
323 pub(crate) fn from_f32(f: f32) -> Option<Number> {
324 if f.is_finite() {
325 let n = {
326 #[cfg(not(feature = "arbitrary_precision"))]
327 {
328 N::Float(f as f64)
329 }
330 #[cfg(feature = "arbitrary_precision")]
331 {
332 zmij::Buffer::new().format_finite(f).to_owned()
333 }
334 };
335 Some(Number { n })
336 } else {
337 None
338 }
339 }
340
341 #[cfg(feature = "arbitrary_precision")]
342 #[doc(hidden)]
344 #[inline]
345 pub fn from_string_unchecked(n: String) -> Self {
346 Number { n }
347 }
348}
349
350impl Display for Number {
351 #[cfg(not(feature = "arbitrary_precision"))]
352 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
353 match self.n {
354 N::PosInt(u) => formatter.write_str(itoa::Buffer::new().format(u)),
355 N::NegInt(i) => formatter.write_str(itoa::Buffer::new().format(i)),
356 N::Float(f) => formatter.write_str(zmij::Buffer::new().format_finite(f)),
357 }
358 }
359
360 #[cfg(feature = "arbitrary_precision")]
361 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
362 Display::fmt(&self.n, formatter)
363 }
364}
365
366impl Debug for Number {
367 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
368 write!(formatter, "Number({})", self)
369 }
370}
371
372impl Serialize for Number {
373 #[cfg(not(feature = "arbitrary_precision"))]
374 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
375 where
376 S: Serializer,
377 {
378 match self.n {
379 N::PosInt(u) => serializer.serialize_u64(u),
380 N::NegInt(i) => serializer.serialize_i64(i),
381 N::Float(f) => serializer.serialize_f64(f),
382 }
383 }
384
385 #[cfg(feature = "arbitrary_precision")]
386 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
387 where
388 S: Serializer,
389 {
390 use serde::ser::SerializeStruct;
391
392 let mut s = tri!(serializer.serialize_struct(TOKEN, 1));
393 tri!(s.serialize_field(TOKEN, &self.n));
394 s.end()
395 }
396}
397
398impl<'de> Deserialize<'de> for Number {
399 #[inline]
400 fn deserialize<D>(deserializer: D) -> Result<Number, D::Error>
401 where
402 D: Deserializer<'de>,
403 {
404 struct NumberVisitor;
405
406 impl<'de> Visitor<'de> for NumberVisitor {
407 type Value = Number;
408
409 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
410 formatter.write_str("a JSON number")
411 }
412
413 fn visit_i64<E>(self, value: i64) -> Result<Number, E> {
414 Ok(value.into())
415 }
416
417 fn visit_i128<E>(self, value: i128) -> Result<Number, E>
418 where
419 E: de::Error,
420 {
421 Number::from_i128(value)
422 .ok_or_else(|| de::Error::custom("JSON number out of range"))
423 }
424
425 fn visit_u64<E>(self, value: u64) -> Result<Number, E> {
426 Ok(value.into())
427 }
428
429 fn visit_u128<E>(self, value: u128) -> Result<Number, E>
430 where
431 E: de::Error,
432 {
433 Number::from_u128(value)
434 .ok_or_else(|| de::Error::custom("JSON number out of range"))
435 }
436
437 fn visit_f64<E>(self, value: f64) -> Result<Number, E>
438 where
439 E: de::Error,
440 {
441 Number::from_f64(value).ok_or_else(|| de::Error::custom("not a JSON number"))
442 }
443
444 #[cfg(feature = "arbitrary_precision")]
445 fn visit_map<V>(self, mut visitor: V) -> Result<Number, V::Error>
446 where
447 V: de::MapAccess<'de>,
448 {
449 let value = tri!(visitor.next_key::<NumberKey>());
450 if value.is_none() {
451 return Err(de::Error::invalid_type(Unexpected::Map, &self));
452 }
453 let v: NumberFromString = tri!(visitor.next_value());
454 Ok(v.value)
455 }
456 }
457
458 deserializer.deserialize_any(NumberVisitor)
459 }
460}
461
462#[cfg(feature = "arbitrary_precision")]
463struct NumberKey;
464
465#[cfg(feature = "arbitrary_precision")]
466impl<'de> de::Deserialize<'de> for NumberKey {
467 fn deserialize<D>(deserializer: D) -> Result<NumberKey, D::Error>
468 where
469 D: de::Deserializer<'de>,
470 {
471 struct FieldVisitor;
472
473 impl<'de> de::Visitor<'de> for FieldVisitor {
474 type Value = ();
475
476 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
477 formatter.write_str("a valid number field")
478 }
479
480 fn visit_str<E>(self, s: &str) -> Result<(), E>
481 where
482 E: de::Error,
483 {
484 if s == TOKEN {
485 Ok(())
486 } else {
487 Err(de::Error::custom("expected field with custom name"))
488 }
489 }
490 }
491
492 tri!(deserializer.deserialize_identifier(FieldVisitor));
493 Ok(NumberKey)
494 }
495}
496
497#[cfg(feature = "arbitrary_precision")]
498pub struct NumberFromString {
499 pub value: Number,
500}
501
502#[cfg(feature = "arbitrary_precision")]
503impl<'de> de::Deserialize<'de> for NumberFromString {
504 fn deserialize<D>(deserializer: D) -> Result<NumberFromString, D::Error>
505 where
506 D: de::Deserializer<'de>,
507 {
508 struct Visitor;
509
510 impl<'de> de::Visitor<'de> for Visitor {
511 type Value = NumberFromString;
512
513 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
514 formatter.write_str("string containing a number")
515 }
516
517 fn visit_str<E>(self, s: &str) -> Result<NumberFromString, E>
518 where
519 E: de::Error,
520 {
521 let n = tri!(s.parse().map_err(de::Error::custom));
522 Ok(NumberFromString { value: n })
523 }
524 }
525
526 deserializer.deserialize_str(Visitor)
527 }
528}
529
530#[cfg(feature = "arbitrary_precision")]
531fn invalid_number() -> Error {
532 Error::syntax(ErrorCode::InvalidNumber, 0, 0)
533}
534
535macro_rules! deserialize_any {
536 (@expand [$($num_string:tt)*]) => {
537 #[cfg(not(feature = "arbitrary_precision"))]
538 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
539 where
540 V: Visitor<'de>,
541 {
542 match self.n {
543 N::PosInt(u) => visitor.visit_u64(u),
544 N::NegInt(i) => visitor.visit_i64(i),
545 N::Float(f) => visitor.visit_f64(f),
546 }
547 }
548
549 #[cfg(feature = "arbitrary_precision")]
550 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
551 where V: Visitor<'de>
552 {
553 if let Some(u) = self.as_u64() {
554 return visitor.visit_u64(u);
555 } else if let Some(i) = self.as_i64() {
556 return visitor.visit_i64(i);
557 } else if let Some(u) = self.as_u128() {
558 return visitor.visit_u128(u);
559 } else if let Some(i) = self.as_i128() {
560 return visitor.visit_i128(i);
561 } else if let Some(f) = self.as_f64() {
562 if zmij::Buffer::new().format_finite(f) == self.n || f.to_string() == self.n {
563 return visitor.visit_f64(f);
564 }
565 }
566
567 visitor.visit_map(NumberDeserializer {
568 number: Some(self.$($num_string)*),
569 })
570 }
571 };
572
573 (owned) => {
574 deserialize_any!(@expand [n]);
575 };
576
577 (ref) => {
578 deserialize_any!(@expand [n.clone()]);
579 };
580}
581
582macro_rules! deserialize_number {
583 ($deserialize:ident => $visit:ident) => {
584 #[cfg(not(feature = "arbitrary_precision"))]
585 fn $deserialize<V>(self, visitor: V) -> Result<V::Value, Error>
586 where
587 V: Visitor<'de>,
588 {
589 self.deserialize_any(visitor)
590 }
591
592 #[cfg(feature = "arbitrary_precision")]
593 fn $deserialize<V>(self, visitor: V) -> Result<V::Value, Error>
594 where
595 V: de::Visitor<'de>,
596 {
597 visitor.$visit(tri!(self.n.parse().map_err(|_| invalid_number())))
598 }
599 };
600}
601
602impl<'de> Deserializer<'de> for Number {
603 type Error = Error;
604
605 deserialize_any!(owned);
606
607 deserialize_number!(deserialize_i8 => visit_i8);
608 deserialize_number!(deserialize_i16 => visit_i16);
609 deserialize_number!(deserialize_i32 => visit_i32);
610 deserialize_number!(deserialize_i64 => visit_i64);
611 deserialize_number!(deserialize_i128 => visit_i128);
612 deserialize_number!(deserialize_u8 => visit_u8);
613 deserialize_number!(deserialize_u16 => visit_u16);
614 deserialize_number!(deserialize_u32 => visit_u32);
615 deserialize_number!(deserialize_u64 => visit_u64);
616 deserialize_number!(deserialize_u128 => visit_u128);
617 deserialize_number!(deserialize_f32 => visit_f32);
618 deserialize_number!(deserialize_f64 => visit_f64);
619
620 forward_to_deserialize_any! {
621 bool char str string bytes byte_buf option unit unit_struct
622 newtype_struct seq tuple tuple_struct map struct enum identifier
623 ignored_any
624 }
625}
626
627impl<'de> Deserializer<'de> for &Number {
628 type Error = Error;
629
630 deserialize_any!(ref);
631
632 deserialize_number!(deserialize_i8 => visit_i8);
633 deserialize_number!(deserialize_i16 => visit_i16);
634 deserialize_number!(deserialize_i32 => visit_i32);
635 deserialize_number!(deserialize_i64 => visit_i64);
636 deserialize_number!(deserialize_i128 => visit_i128);
637 deserialize_number!(deserialize_u8 => visit_u8);
638 deserialize_number!(deserialize_u16 => visit_u16);
639 deserialize_number!(deserialize_u32 => visit_u32);
640 deserialize_number!(deserialize_u64 => visit_u64);
641 deserialize_number!(deserialize_u128 => visit_u128);
642 deserialize_number!(deserialize_f32 => visit_f32);
643 deserialize_number!(deserialize_f64 => visit_f64);
644
645 forward_to_deserialize_any! {
646 bool char str string bytes byte_buf option unit unit_struct
647 newtype_struct seq tuple tuple_struct map struct enum identifier
648 ignored_any
649 }
650}
651
652#[cfg(feature = "arbitrary_precision")]
653pub(crate) struct NumberDeserializer {
654 pub number: Option<String>,
655}
656
657#[cfg(feature = "arbitrary_precision")]
658impl<'de> MapAccess<'de> for NumberDeserializer {
659 type Error = Error;
660
661 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
662 where
663 K: de::DeserializeSeed<'de>,
664 {
665 if self.number.is_none() {
666 return Ok(None);
667 }
668 seed.deserialize(NumberFieldDeserializer).map(Some)
669 }
670
671 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
672 where
673 V: de::DeserializeSeed<'de>,
674 {
675 seed.deserialize(self.number.take().unwrap().into_deserializer())
676 }
677}
678
679#[cfg(feature = "arbitrary_precision")]
680struct NumberFieldDeserializer;
681
682#[cfg(feature = "arbitrary_precision")]
683impl<'de> Deserializer<'de> for NumberFieldDeserializer {
684 type Error = Error;
685
686 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
687 where
688 V: de::Visitor<'de>,
689 {
690 visitor.visit_borrowed_str(TOKEN)
691 }
692
693 forward_to_deserialize_any! {
694 bool u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 char str string seq
695 bytes byte_buf map struct option unit newtype_struct ignored_any
696 unit_struct tuple_struct tuple enum identifier
697 }
698}
699
700impl From<ParserNumber> for Number {
701 fn from(value: ParserNumber) -> Self {
702 let n = match value {
703 ParserNumber::F64(f) => {
704 #[cfg(not(feature = "arbitrary_precision"))]
705 {
706 N::Float(f)
707 }
708 #[cfg(feature = "arbitrary_precision")]
709 {
710 zmij::Buffer::new().format_finite(f).to_owned()
711 }
712 }
713 ParserNumber::U64(u) => {
714 #[cfg(not(feature = "arbitrary_precision"))]
715 {
716 N::PosInt(u)
717 }
718 #[cfg(feature = "arbitrary_precision")]
719 {
720 itoa::Buffer::new().format(u).to_owned()
721 }
722 }
723 ParserNumber::I64(i) => {
724 #[cfg(not(feature = "arbitrary_precision"))]
725 {
726 N::NegInt(i)
727 }
728 #[cfg(feature = "arbitrary_precision")]
729 {
730 itoa::Buffer::new().format(i).to_owned()
731 }
732 }
733 #[cfg(feature = "arbitrary_precision")]
734 ParserNumber::String(s) => s,
735 };
736 Number { n }
737 }
738}
739
740macro_rules! impl_from_unsigned {
741 (
742 $($ty:ty),*
743 ) => {
744 $(
745 impl From<$ty> for Number {
746 fn from(u: $ty) -> Self {
747 let n = {
748 #[cfg(not(feature = "arbitrary_precision"))]
749 { N::PosInt(u as u64) }
750 #[cfg(feature = "arbitrary_precision")]
751 {
752 itoa::Buffer::new().format(u).to_owned()
753 }
754 };
755 Number { n }
756 }
757 }
758 )*
759 };
760}
761
762macro_rules! impl_from_signed {
763 (
764 $($ty:ty),*
765 ) => {
766 $(
767 impl From<$ty> for Number {
768 fn from(i: $ty) -> Self {
769 let n = {
770 #[cfg(not(feature = "arbitrary_precision"))]
771 {
772 if i < 0 {
773 N::NegInt(i as i64)
774 } else {
775 N::PosInt(i as u64)
776 }
777 }
778 #[cfg(feature = "arbitrary_precision")]
779 {
780 itoa::Buffer::new().format(i).to_owned()
781 }
782 };
783 Number { n }
784 }
785 }
786 )*
787 };
788}
789
790impl_from_unsigned!(u8, u16, u32, u64, usize);
791impl_from_signed!(i8, i16, i32, i64, isize);
792
793#[cfg(feature = "arbitrary_precision")]
794impl_from_unsigned!(u128);
795#[cfg(feature = "arbitrary_precision")]
796impl_from_signed!(i128);
797
798impl Number {
799 #[cfg(not(feature = "arbitrary_precision"))]
800 #[cold]
801 pub(crate) fn unexpected(&self) -> Unexpected {
802 match self.n {
803 N::PosInt(u) => Unexpected::Unsigned(u),
804 N::NegInt(i) => Unexpected::Signed(i),
805 N::Float(f) => Unexpected::Float(f),
806 }
807 }
808
809 #[cfg(feature = "arbitrary_precision")]
810 #[cold]
811 pub(crate) fn unexpected(&self) -> Unexpected {
812 Unexpected::Other("number")
813 }
814}