diff --git a/src/value/ser.rs b/src/value/ser.rs index 892a63d5f..a29814e92 100644 --- a/src/value/ser.rs +++ b/src/value/ser.rs @@ -5,6 +5,8 @@ use crate::value::{to_value, Value}; use alloc::borrow::ToOwned; use alloc::string::{String, ToString}; use alloc::vec::Vec; +#[cfg(not(feature = "arbitrary_precision"))] +use core::convert::TryFrom; use core::fmt::Display; use core::result; use serde::ser::{Impossible, Serialize}; @@ -92,9 +94,22 @@ impl serde::Serializer for Serializer { Ok(Value::Number(value.into())) } - #[cfg(feature = "arbitrary_precision")] fn serialize_i128(self, value: i128) -> Result { - Ok(Value::Number(value.into())) + #[cfg(feature = "arbitrary_precision")] + { + Ok(Value::Number(value.into())) + } + + #[cfg(not(feature = "arbitrary_precision"))] + { + if let Ok(value) = u64::try_from(value) { + Ok(Value::Number(value.into())) + } else if let Ok(value) = i64::try_from(value) { + Ok(Value::Number(value.into())) + } else { + Err(Error::syntax(ErrorCode::NumberOutOfRange, 0, 0)) + } + } } #[inline] @@ -117,9 +132,20 @@ impl serde::Serializer for Serializer { Ok(Value::Number(value.into())) } - #[cfg(feature = "arbitrary_precision")] fn serialize_u128(self, value: u128) -> Result { - Ok(Value::Number(value.into())) + #[cfg(feature = "arbitrary_precision")] + { + Ok(Value::Number(value.into())) + } + + #[cfg(not(feature = "arbitrary_precision"))] + { + if let Ok(value) = u64::try_from(value) { + Ok(Value::Number(value.into())) + } else { + Err(Error::syntax(ErrorCode::NumberOutOfRange, 0, 0)) + } + } } #[inline] diff --git a/tests/test.rs b/tests/test.rs index c2050724b..f62a545e7 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -2180,6 +2180,27 @@ fn test_integer128() { ]); } +#[test] +fn test_integer128_to_value() { + let signed = &[i128::from(i64::min_value()), i128::from(u64::max_value())]; + let unsigned = &[0, u128::from(u64::max_value())]; + + for integer128 in signed { + let expected = integer128.to_string(); + assert_eq!(to_value(integer128).unwrap().to_string(), expected); + } + + for integer128 in unsigned { + let expected = integer128.to_string(); + assert_eq!(to_value(integer128).unwrap().to_string(), expected); + } + + if !cfg!(feature = "arbitrary_precision") { + let err = to_value(u128::from(u64::max_value()) + 1).unwrap_err(); + assert_eq!(err.to_string(), "number out of range"); + } +} + #[cfg(feature = "raw_value")] #[test] fn test_borrowed_raw_value() {