Arbitrary-precision numerics support (#416)

Added support for arbitrary-precision numerics, in a similar way that the toml crate does for date-times (using an internal special struct).
This commit is contained in:
Alexander Regueiro 2018-03-21 19:09:36 +00:00 committed by David Tolnay
parent 21d623d7bb
commit 31bba4b5a1
9 changed files with 1696 additions and 299 deletions

View File

@ -37,3 +37,10 @@ default = []
# This allows data to be read into a Value and written back to a JSON string
# while preserving the order of map keys in the input.
preserve_order = ["linked-hash-map"]
# Use `String` to represent numbers internally, thus allowing the serialization
# and deserialization of numbers of arbitrary size/precision, instead of just
# the primitive integers and floats.
# This feature does not provide provide the ability to do arithmetic on
# arbitrary-precision numbers; this is left to the discretion of the consumer.
arbitrary_precision = []

282
src/de.rs
View File

@ -20,6 +20,9 @@ use read::{self, Reference};
pub use read::{Read, IoRead, SliceRead, StrRead};
#[cfg(feature = "arbitrary_precision")]
use number::NumberDeserializer;
//////////////////////////////////////////////////////////////////////////////
/// A structure that deserializes JSON into Rust values.
@ -80,10 +83,14 @@ macro_rules! overflow {
}
}
enum Number {
// Not public API. Should be pub(crate).
#[doc(hidden)]
pub enum Number {
F64(f64),
U64(u64),
I64(i64),
#[cfg(feature = "arbitrary_precision")]
String(String),
}
impl Number {
@ -95,6 +102,12 @@ impl Number {
Number::F64(x) => visitor.visit_f64(x),
Number::U64(x) => visitor.visit_u64(x),
Number::I64(x) => visitor.visit_i64(x),
#[cfg(feature = "arbitrary_precision")]
Number::String(x) => {
visitor.visit_map(NumberDeserializer {
number: x.into(),
})
},
}
}
@ -103,6 +116,8 @@ impl Number {
Number::F64(x) => de::Error::invalid_type(Unexpected::Float(x), exp),
Number::U64(x) => de::Error::invalid_type(Unexpected::Unsigned(x), exp),
Number::I64(x) => de::Error::invalid_type(Unexpected::Signed(x), exp),
#[cfg(feature = "arbitrary_precision")]
Number::String(_) => de::Error::invalid_type(Unexpected::Other("number"), exp),
}
}
}
@ -209,13 +224,13 @@ impl<'de, R: Read<'de>> Deserializer<R> {
}
b'-' => {
self.eat_char();
match self.parse_integer(false) {
match self.parse_any_number(false) {
Ok(n) => n.invalid_type(exp),
Err(err) => return err,
}
}
b'0'...b'9' => {
match self.parse_integer(true) {
match self.parse_any_number(true) {
Ok(n) => n.invalid_type(exp),
Err(err) => return err,
}
@ -240,7 +255,7 @@ impl<'de, R: Read<'de>> Deserializer<R> {
self.fix_position(err)
}
fn deserialize_number<V>(&mut self, visitor: V) -> Result<V::Value>
fn deserialize_prim_number<V>(&mut self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
@ -476,6 +491,165 @@ impl<'de, R: Read<'de>> Deserializer<R> {
Ok(if positive { 0.0 } else { -0.0 })
}
// Not public API. Should be pub(crate).
#[doc(hidden)]
pub fn parse_any_signed_number(&mut self) -> Result<Number> {
let peek = match try!(self.peek()) {
Some(b) => b,
None => {
return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
}
};
let value = match peek {
b'-' => {
self.eat_char();
self.parse_any_number(false)
}
b'0'...b'9' => {
self.parse_any_number(true)
}
_ => Err(self.peek_error(ErrorCode::InvalidNumber)),
};
let value = match try!(self.peek()) {
Some(_) => Err(self.peek_error(ErrorCode::InvalidNumber)),
None => value,
};
match value {
Ok(value) => Ok(value),
// The de::Error impl creates errors with unknown line and column.
// Fill in the position here by looking at the current index in the
// input. There is no way to tell whether this should call `error`
// or `peek_error` so pick the one that seems correct more often.
// Worst case, the position is off by one character.
Err(err) => Err(self.fix_position(err)),
}
}
#[cfg(not(feature = "arbitrary_precision"))]
fn parse_any_number(&mut self, pos: bool) -> Result<Number>
{
self.parse_integer(pos)
}
#[cfg(feature = "arbitrary_precision")]
fn parse_any_number(&mut self, pos: bool) -> Result<Number>
{
let mut buf = String::with_capacity(16);
if !pos {
buf.push('-');
}
self.scan_integer(&mut buf)?;
Ok(Number::String(buf))
}
#[cfg(feature = "arbitrary_precision")]
fn scan_or_null(&mut self, buf: &mut String) -> Result<u8> {
match try!(self.next_char()) {
Some(b) => {
buf.push(b as char);
Ok(b)
}
None => {
Ok(b'\x00')
}
}
}
#[cfg(feature = "arbitrary_precision")]
fn scan_integer(&mut self, buf: &mut String) -> Result<()> {
match try!(self.scan_or_null(buf)) {
b'0' => {
// There can be only one leading '0'.
match try!(self.peek_or_null()) {
b'0'...b'9' => {
Err(self.peek_error(ErrorCode::InvalidNumber))
}
_ => self.scan_number(buf),
}
}
b'1'...b'9' => {
loop {
match try!(self.peek_or_null()) {
c @ b'0'...b'9' => {
self.eat_char();
buf.push(c as char);
}
_ => {
return self.scan_number(buf);
}
}
}
}
_ => Err(self.error(ErrorCode::InvalidNumber)),
}
}
#[cfg(feature = "arbitrary_precision")]
fn scan_number(&mut self, buf: &mut String) -> Result<()> {
match try!(self.peek_or_null()) {
b'.' => self.scan_decimal(buf),
b'e' | b'E' => self.scan_exponent(buf),
_ => Ok(()),
}
}
#[cfg(feature = "arbitrary_precision")]
fn scan_decimal(&mut self, buf: &mut String) -> Result<()> {
self.eat_char();
buf.push('.');
let mut at_least_one_digit = false;
while let c @ b'0'...b'9' = try!(self.peek_or_null()) {
self.eat_char();
buf.push(c as char);
at_least_one_digit = true;
}
if !at_least_one_digit {
return Err(self.peek_error(ErrorCode::InvalidNumber));
}
match try!(self.peek_or_null()) {
b'e' | b'E' => self.scan_exponent(buf),
_ => Ok(()),
}
}
#[cfg(feature = "arbitrary_precision")]
fn scan_exponent(&mut self, buf: &mut String) -> Result<()> {
self.eat_char();
buf.push('e');
match try!(self.peek_or_null()) {
b'+' => {
self.eat_char();
}
b'-' => {
self.eat_char();
buf.push('-');
}
_ => {}
}
// Make sure a digit follows the exponent place.
match try!(self.scan_or_null(buf)) {
b'0'...b'9' => {}
_ => {
return Err(self.error(ErrorCode::InvalidNumber));
}
}
while let c @ b'0'...b'9' = try!(self.peek_or_null()) {
self.eat_char();
buf.push(c as char);
}
Ok(())
}
fn f64_from_parts(
&mut self,
positive: bool,
@ -796,6 +970,17 @@ static POW10: [f64; 309] =
1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299,
1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308];
macro_rules! deserialize_prim_number {
($method:ident) => {
fn $method<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
self.deserialize_prim_number(visitor)
}
}
}
impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer<R> {
type Error = Error;
@ -829,9 +1014,11 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer<R> {
}
b'-' => {
self.eat_char();
try!(self.parse_integer(false)).visit(visitor)
try!(self.parse_any_number(false)).visit(visitor)
}
b'0'...b'9' => {
try!(self.parse_any_number(true)).visit(visitor)
}
b'0'...b'9' => try!(self.parse_integer(true)).visit(visitor),
b'"' => {
self.eat_char();
self.str_buf.clear();
@ -917,75 +1104,16 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer<R> {
}
}
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
self.deserialize_number(visitor)
}
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
self.deserialize_number(visitor)
}
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
self.deserialize_number(visitor)
}
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
self.deserialize_number(visitor)
}
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
self.deserialize_number(visitor)
}
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
self.deserialize_number(visitor)
}
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
self.deserialize_number(visitor)
}
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
self.deserialize_number(visitor)
}
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
self.deserialize_number(visitor)
}
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
self.deserialize_number(visitor)
}
deserialize_prim_number!(deserialize_i8);
deserialize_prim_number!(deserialize_i16);
deserialize_prim_number!(deserialize_i32);
deserialize_prim_number!(deserialize_i64);
deserialize_prim_number!(deserialize_u8);
deserialize_prim_number!(deserialize_u16);
deserialize_prim_number!(deserialize_u32);
deserialize_prim_number!(deserialize_u64);
deserialize_prim_number!(deserialize_f32);
deserialize_prim_number!(deserialize_f64);
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
where
@ -1646,8 +1774,8 @@ struct MapKey<'a, R: 'a> {
}
macro_rules! deserialize_integer_key {
($deserialize:ident => $visit:ident) => {
fn $deserialize<V>(self, visitor: V) -> Result<V::Value>
($method:ident => $visit:ident) => {
fn $method<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{

View File

@ -7,11 +7,34 @@
// except according to those terms.
use error::Error;
use num_traits::NumCast;
use serde::de::{self, Visitor, Unexpected};
use serde::{Serialize, Serializer, Deserialize, Deserializer};
use std::fmt::{self, Debug, Display};
use std::i64;
use std::str::FromStr;
#[cfg(not(feature = "arbitrary_precision"))]
use num_traits::{NumCast};
#[cfg(feature = "arbitrary_precision")]
use dtoa;
#[cfg(feature = "arbitrary_precision")]
use itoa;
#[cfg(feature = "arbitrary_precision")]
use serde::de::{IntoDeserializer, MapAccess};
#[cfg(feature = "arbitrary_precision")]
use error::{ErrorCode};
#[cfg(feature = "arbitrary_precision")]
/// Not public API. Should be pub(crate).
#[doc(hidden)]
pub const SERDE_STRUCT_FIELD_NAME: &'static str = "$__serde_private_number";
#[cfg(feature = "arbitrary_precision")]
/// Not public API. Should be pub(crate).
#[doc(hidden)]
pub const SERDE_STRUCT_NAME: &'static str = "$__serde_private_Number";
/// Represents a JSON number, whether integer or floating point.
#[derive(Clone, PartialEq)]
@ -19,6 +42,7 @@ pub struct Number {
n: N,
}
#[cfg(not(feature = "arbitrary_precision"))]
#[derive(Copy, Clone, PartialEq)]
enum N {
PosInt(u64),
@ -28,6 +52,9 @@ enum N {
Float(f64),
}
#[cfg(feature = "arbitrary_precision")]
type N = String;
impl Number {
/// Returns true if the `Number` is an integer between `i64::MIN` and
/// `i64::MAX`.
@ -56,11 +83,14 @@ impl Number {
/// ```
#[inline]
pub fn is_i64(&self) -> bool {
#[cfg(not(feature = "arbitrary_precision"))]
match self.n {
N::PosInt(v) => v <= i64::max_value() as u64,
N::NegInt(_) => true,
N::Float(_) => false,
}
#[cfg(feature = "arbitrary_precision")]
self.as_i64().is_some()
}
/// Returns true if the `Number` is an integer between zero and `u64::MAX`.
@ -86,10 +116,13 @@ impl Number {
/// ```
#[inline]
pub fn is_u64(&self) -> bool {
#[cfg(not(feature = "arbitrary_precision"))]
match self.n {
N::PosInt(_) => true,
N::NegInt(_) | N::Float(_) => false,
}
#[cfg(feature = "arbitrary_precision")]
self.as_u64().is_some()
}
/// Returns true if the `Number` can be represented by f64.
@ -116,10 +149,21 @@ impl Number {
/// ```
#[inline]
pub fn is_f64(&self) -> bool {
#[cfg(not(feature = "arbitrary_precision"))]
match self.n {
N::Float(_) => true,
N::PosInt(_) | N::NegInt(_) => false,
}
#[cfg(feature = "arbitrary_precision")]
{
for c in self.n.chars() {
if c == '.' || c == 'e' || c == 'E' {
return self.n.parse::<f64>().ok()
.map_or(false, |f| f.is_finite());
}
}
false
}
}
/// If the `Number` is an integer, represent it as i64 if possible. Returns
@ -142,11 +186,14 @@ impl Number {
/// ```
#[inline]
pub fn as_i64(&self) -> Option<i64> {
#[cfg(not(feature = "arbitrary_precision"))]
match self.n {
N::PosInt(n) => NumCast::from(n),
N::NegInt(n) => Some(n),
N::Float(_) => None,
}
#[cfg(feature = "arbitrary_precision")]
self.n.parse().ok()
}
/// If the `Number` is an integer, represent it as u64 if possible. Returns
@ -166,11 +213,14 @@ impl Number {
/// ```
#[inline]
pub fn as_u64(&self) -> Option<u64> {
#[cfg(not(feature = "arbitrary_precision"))]
match self.n {
N::PosInt(n) => Some(n),
N::NegInt(n) => NumCast::from(n),
N::Float(_) => None,
}
#[cfg(feature = "arbitrary_precision")]
self.n.parse().ok()
}
/// Represents the number as f64 if possible. Returns None otherwise.
@ -189,11 +239,14 @@ impl Number {
/// ```
#[inline]
pub fn as_f64(&self) -> Option<f64> {
#[cfg(not(feature = "arbitrary_precision"))]
match self.n {
N::PosInt(n) => NumCast::from(n),
N::NegInt(n) => NumCast::from(n),
N::Float(n) => Some(n),
}
#[cfg(feature = "arbitrary_precision")]
self.n.parse().ok()
}
/// Converts a finite `f64` to a `Number`. Infinite or NaN values are not JSON
@ -211,24 +264,49 @@ impl Number {
#[inline]
pub fn from_f64(f: f64) -> Option<Number> {
if f.is_finite() {
Some(Number { n: N::Float(f) })
let n = {
#[cfg(not(feature = "arbitrary_precision"))]
{ N::Float(f) }
#[cfg(feature = "arbitrary_precision")]
{
let mut buf = Vec::new();
dtoa::write(&mut buf, f).unwrap();
String::from_utf8(buf).unwrap()
}
};
Some(Number { n: n })
} else {
None
}
}
#[cfg(feature = "arbitrary_precision")]
/// Not public API. Only tests use this.
#[doc(hidden)]
#[inline]
pub fn from_string_unchecked(n: String) -> Self {
Number { n: n }
}
}
impl fmt::Display for Number {
#[cfg(not(feature = "arbitrary_precision"))]
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
match self.n {
N::PosInt(i) => Display::fmt(&i, formatter),
N::PosInt(u) => Display::fmt(&u, formatter),
N::NegInt(i) => Display::fmt(&i, formatter),
N::Float(f) => Display::fmt(&f, formatter),
}
}
#[cfg(feature = "arbitrary_precision")]
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(&self.n, formatter)
}
}
impl Debug for Number {
#[cfg(not(feature = "arbitrary_precision"))]
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let mut debug = formatter.debug_tuple("Number");
match self.n {
@ -244,20 +322,39 @@ impl Debug for Number {
}
debug.finish()
}
#[cfg(feature = "arbitrary_precision")]
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "Number({})", &self.n)
}
}
impl Serialize for Number {
#[cfg(not(feature = "arbitrary_precision"))]
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self.n {
N::PosInt(i) => serializer.serialize_u64(i),
N::PosInt(u) => serializer.serialize_u64(u),
N::NegInt(i) => serializer.serialize_i64(i),
N::Float(f) => serializer.serialize_f64(f),
}
}
#[cfg(feature = "arbitrary_precision")]
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
use serde::ser::SerializeStruct;
let mut s = serializer.serialize_struct(SERDE_STRUCT_NAME, 1)?;
s.serialize_field(SERDE_STRUCT_FIELD_NAME, &self.n)?;
s.end()
}
}
impl<'de> Deserialize<'de> for Number {
@ -272,7 +369,7 @@ impl<'de> Deserialize<'de> for Number {
type Value = Number;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a number")
formatter.write_str("a JSON number")
}
#[inline]
@ -292,90 +389,355 @@ impl<'de> Deserialize<'de> for Number {
{
Number::from_f64(value).ok_or_else(|| de::Error::custom("not a JSON number"))
}
#[cfg(feature = "arbitrary_precision")]
#[inline]
fn visit_map<V>(self, mut visitor: V) -> Result<Number, V::Error>
where
V: de::MapAccess<'de>
{
let value = visitor.next_key::<NumberKey>()?;
if value.is_none() {
return Err(de::Error::invalid_type(Unexpected::Map, &self));
}
let v: NumberFromString = visitor.next_value()?;
Ok(v.value)
}
}
deserializer.deserialize_any(NumberVisitor)
}
}
#[cfg(feature = "arbitrary_precision")]
struct NumberKey;
#[cfg(feature = "arbitrary_precision")]
impl<'de> de::Deserialize<'de> for NumberKey {
fn deserialize<D>(deserializer: D) -> Result<NumberKey, D::Error>
where
D: de::Deserializer<'de>
{
struct FieldVisitor;
impl<'de> de::Visitor<'de> for FieldVisitor {
type Value = ();
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a valid number field")
}
fn visit_str<E>(self, s: &str) -> Result<(), E>
where E: de::Error
{
if s == SERDE_STRUCT_FIELD_NAME {
Ok(())
} else {
Err(de::Error::custom("expected field with custom name"))
}
}
}
deserializer.deserialize_identifier(FieldVisitor)?;
Ok(NumberKey)
}
}
#[cfg(feature = "arbitrary_precision")]
pub struct NumberFromString {
pub value: Number,
}
#[cfg(feature = "arbitrary_precision")]
impl<'de> de::Deserialize<'de> for NumberFromString {
fn deserialize<D>(deserializer: D) -> Result<NumberFromString, D::Error>
where
D: de::Deserializer<'de>
{
struct Visitor;
impl<'de> de::Visitor<'de> for Visitor {
type Value = NumberFromString;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("string containing a number")
}
fn visit_str<E>(self, s: &str) -> Result<NumberFromString, E>
where E: de::Error,
{
let n = try!(s.parse().map_err(de::Error::custom));
Ok(NumberFromString { value: n })
}
}
deserializer.deserialize_str(Visitor)
}
}
#[cfg(feature = "arbitrary_precision")]
fn invalid_number() -> Error {
Error::syntax(ErrorCode::InvalidNumber, 0, 0)
}
macro_rules! deserialize_any {
(@expand [$($num_string:tt)*]) => {
#[cfg(not(feature = "arbitrary_precision"))]
#[inline]
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
match self.n {
N::PosInt(u) => visitor.visit_u64(u),
N::NegInt(i) => visitor.visit_i64(i),
N::Float(f) => visitor.visit_f64(f),
}
}
#[cfg(feature = "arbitrary_precision")]
#[inline]
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
where V: Visitor<'de>
{
if let Some(u) = self.as_u64() {
return visitor.visit_u64(u);
} else if let Some(i) = self.as_i64() {
return visitor.visit_i64(i);
} else if let Some(f) = self.as_f64() {
if f.to_string() == self.n {
return visitor.visit_f64(f);
}
}
visitor.visit_map(NumberDeserializer {
number: Some(self.$($num_string)*),
})
}
};
(owned) => {
deserialize_any!(@expand [n]);
};
(ref) => {
deserialize_any!(@expand [n.clone()]);
};
}
macro_rules! deserialize_number {
($deserialize:ident => $visit:ident) => {
#[cfg(not(feature = "arbitrary_precision"))]
fn $deserialize<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
self.deserialize_any(visitor)
}
#[cfg(feature = "arbitrary_precision")]
fn $deserialize<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: de::Visitor<'de>,
{
visitor.$visit(self.n.parse().map_err(|_| invalid_number())?)
}
}
}
impl<'de> Deserializer<'de> for Number {
type Error = Error;
#[inline]
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
match self.n {
N::PosInt(i) => visitor.visit_u64(i),
N::NegInt(i) => visitor.visit_i64(i),
N::Float(f) => visitor.visit_f64(f),
}
}
deserialize_any!(owned);
deserialize_number!(deserialize_i8 => visit_i8);
deserialize_number!(deserialize_i16 => visit_i16);
deserialize_number!(deserialize_i32 => visit_i32);
deserialize_number!(deserialize_i64 => visit_i64);
deserialize_number!(deserialize_u8 => visit_u8);
deserialize_number!(deserialize_u16 => visit_u16);
deserialize_number!(deserialize_u32 => visit_u32);
deserialize_number!(deserialize_u64 => visit_u64);
deserialize_number!(deserialize_f32 => visit_f32);
deserialize_number!(deserialize_f64 => visit_f64);
forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
byte_buf option unit unit_struct newtype_struct seq tuple
tuple_struct map struct enum identifier ignored_any
bool char str string bytes byte_buf option unit unit_struct
newtype_struct seq tuple tuple_struct map struct enum identifier
ignored_any
}
}
impl<'de, 'a> Deserializer<'de> for &'a Number {
type Error = Error;
#[inline]
deserialize_any!(ref);
deserialize_number!(deserialize_i8 => visit_i8);
deserialize_number!(deserialize_i16 => visit_i16);
deserialize_number!(deserialize_i32 => visit_i32);
deserialize_number!(deserialize_i64 => visit_i64);
deserialize_number!(deserialize_u8 => visit_u8);
deserialize_number!(deserialize_u16 => visit_u16);
deserialize_number!(deserialize_u32 => visit_u32);
deserialize_number!(deserialize_u64 => visit_u64);
deserialize_number!(deserialize_f32 => visit_f32);
deserialize_number!(deserialize_f64 => visit_f64);
forward_to_deserialize_any! {
bool char str string bytes byte_buf option unit unit_struct
newtype_struct seq tuple tuple_struct map struct enum identifier
ignored_any
}
}
#[cfg(feature = "arbitrary_precision")]
// Not public API. Should be pub(crate).
#[doc(hidden)]
pub struct NumberDeserializer {
pub number: Option<String>,
}
#[cfg(feature = "arbitrary_precision")]
impl<'de> MapAccess<'de> for NumberDeserializer {
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
where
K: de::DeserializeSeed<'de>,
{
if self.number.is_none() {
return Ok(None)
}
seed.deserialize(NumberFieldDeserializer).map(Some)
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
where
V: de::DeserializeSeed<'de>,
{
seed.deserialize(self.number.take().unwrap().into_deserializer())
}
}
#[cfg(feature = "arbitrary_precision")]
struct NumberFieldDeserializer;
#[cfg(feature = "arbitrary_precision")]
impl<'de> Deserializer<'de> for NumberFieldDeserializer {
type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
V: de::Visitor<'de>,
{
match self.n {
N::PosInt(i) => visitor.visit_u64(i),
N::NegInt(i) => visitor.visit_i64(i),
N::Float(f) => visitor.visit_f64(f),
}
visitor.visit_borrowed_str(SERDE_STRUCT_FIELD_NAME)
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
byte_buf option unit unit_struct newtype_struct seq tuple
tuple_struct map struct enum identifier ignored_any
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
bytes byte_buf map struct option unit newtype_struct
ignored_any unit_struct tuple_struct tuple enum identifier
}
}
macro_rules! from_signed {
($($signed_ty:ident)*) => {
impl FromStr for Number {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
super::de::Deserializer::from_str(s).parse_any_signed_number().map(|n| n.into())
}
}
impl From<super::de::Number> for Number {
fn from(value: super::de::Number) -> Self {
let n = match value {
super::de::Number::F64(f) => {
#[cfg(not(feature = "arbitrary_precision"))]
{ N::Float(f) }
#[cfg(feature = "arbitrary_precision")]
{ f.to_string() }
},
super::de::Number::U64(u) => {
#[cfg(not(feature = "arbitrary_precision"))]
{ N::PosInt(u) }
#[cfg(feature = "arbitrary_precision")]
{ u.to_string() }
},
super::de::Number::I64(i) => {
#[cfg(not(feature = "arbitrary_precision"))]
{ N::NegInt(i) }
#[cfg(feature = "arbitrary_precision")]
{ i.to_string() }
},
#[cfg(feature = "arbitrary_precision")]
super::de::Number::String(s) => s,
};
Number { n: n }
}
}
macro_rules! impl_from_unsigned {
(
$($ty:ty),*
) => {
$(
impl From<$signed_ty> for Number {
impl From<$ty> for Number {
#[inline]
fn from(i: $signed_ty) -> Self {
if i < 0 {
Number { n: N::NegInt(i as i64) }
} else {
Number { n: N::PosInt(i as u64) }
}
fn from(u: $ty) -> Self {
let n = {
#[cfg(not(feature = "arbitrary_precision"))]
{ N::PosInt(u as u64) }
#[cfg(feature = "arbitrary_precision")]
{
let mut buf = Vec::new();
itoa::write(&mut buf, u).unwrap();
String::from_utf8(buf).unwrap()
}
};
Number { n: n }
}
}
)*
};
}
macro_rules! from_unsigned {
($($unsigned_ty:ident)*) => {
macro_rules! impl_from_signed {
(
$($ty:ty),*
) => {
$(
impl From<$unsigned_ty> for Number {
impl From<$ty> for Number {
#[inline]
fn from(u: $unsigned_ty) -> Self {
Number { n: N::PosInt(u as u64) }
fn from(i: $ty) -> Self {
let n = {
#[cfg(not(feature = "arbitrary_precision"))]
{
if i < 0 {
N::NegInt(i as i64)
} else {
N::PosInt(i as u64)
}
}
#[cfg(feature = "arbitrary_precision")]
{
let mut buf = Vec::new();
itoa::write(&mut buf, i).unwrap();
String::from_utf8(buf).unwrap()
}
};
Number { n: n }
}
}
)*
};
}
from_signed!(i8 i16 i32 i64 isize);
from_unsigned!(u8 u16 u32 u64 usize);
impl_from_unsigned!(u8, u16, u32, u64, usize);
impl_from_signed!(i8, i16, i32, i64, isize);
impl Number {
#[cfg(not(feature = "arbitrary_precision"))]
// Not public API. Should be pub(crate).
#[doc(hidden)]
pub fn unexpected(&self) -> Unexpected {
@ -385,4 +747,11 @@ impl Number {
N::Float(f) => Unexpected::Float(f),
}
}
#[cfg(feature = "arbitrary_precision")]
// Not public API. Should be pub(crate).
#[doc(hidden)]
pub fn unexpected(&self) -> Unexpected {
Unexpected::Other("number")
}
}

View File

@ -19,6 +19,12 @@ use super::error::{Error, ErrorCode, Result};
use itoa;
use dtoa;
#[cfg(feature = "arbitrary_precision")]
use serde::{Serialize};
#[cfg(feature = "arbitrary_precision")]
use number::{SERDE_STRUCT_NAME, SERDE_STRUCT_FIELD_NAME};
/// A structure for serializing Rust values into JSON.
pub struct Serializer<W, F = CompactFormatter> {
writer: W,
@ -347,10 +353,10 @@ where
.map_err(Error::io)
);
Ok(
Compound {
Compound::Map {
ser: self,
state: State::Empty,
},
}
)
} else {
try!(
@ -359,10 +365,10 @@ where
.map_err(Error::io)
);
Ok(
Compound {
Compound::Map {
ser: self,
state: State::First,
},
}
)
}
}
@ -427,10 +433,10 @@ where
.map_err(Error::io)
);
Ok(
Compound {
Compound::Map {
ser: self,
state: State::Empty,
},
}
)
} else {
try!(
@ -439,19 +445,30 @@ where
.map_err(Error::io)
);
Ok(
Compound {
Compound::Map {
ser: self,
state: State::First,
},
}
)
}
}
#[cfg(not(feature = "arbitrary_precision"))]
#[inline]
fn serialize_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
self.serialize_map(Some(len))
}
#[cfg(feature = "arbitrary_precision")]
#[inline]
fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
if name == SERDE_STRUCT_NAME {
Ok(Compound::Number { ser: self })
} else {
self.serialize_map(Some(len))
}
}
#[inline]
fn serialize_struct_variant(
self,
@ -540,18 +557,26 @@ where
}
}
#[doc(hidden)]
#[derive(Eq, PartialEq)]
/// Not public API. Should be pub(crate).
#[doc(hidden)]
pub enum State {
Empty,
First,
Rest,
}
/// Not public API. Should be pub(crate).
#[doc(hidden)]
pub struct Compound<'a, W: 'a, F: 'a> {
ser: &'a mut Serializer<W, F>,
state: State,
pub enum Compound<'a, W: 'a, F: 'a> {
Map {
ser: &'a mut Serializer<W, F>,
state: State,
},
#[cfg(feature = "arbitrary_precision")]
Number {
ser: &'a mut Serializer<W, F>,
},
}
impl<'a, W, F> ser::SerializeSeq for Compound<'a, W, F>
@ -567,37 +592,46 @@ where
where
T: ser::Serialize,
{
try!(
self.ser
.formatter
.begin_array_value(&mut self.ser.writer, self.state == State::First)
.map_err(Error::io)
);
self.state = State::Rest;
try!(value.serialize(&mut *self.ser));
try!(
self.ser
.formatter
.end_array_value(&mut self.ser.writer)
.map_err(Error::io)
);
Ok(())
match *self {
Compound::Map { ref mut ser, ref mut state } => {
try!(
ser.formatter
.begin_array_value(&mut ser.writer, *state == State::First)
.map_err(Error::io)
);
*state = State::Rest;
try!(value.serialize(&mut **ser));
try!(
ser.formatter
.end_array_value(&mut ser.writer)
.map_err(Error::io)
);
Ok(())
},
#[cfg(feature = "arbitrary_precision")]
Compound::Number { .. } => unreachable!(),
}
}
#[inline]
fn end(self) -> Result<()> {
match self.state {
State::Empty => {}
_ => {
try!(
self.ser
.formatter
.end_array(&mut self.ser.writer)
.map_err(Error::io)
)
}
match self {
Compound::Map { ser, state } => {
match state {
State::Empty => {}
_ => {
try!(
ser.formatter
.end_array(&mut ser.writer)
.map_err(Error::io)
)
}
}
Ok(())
},
#[cfg(feature = "arbitrary_precision")]
Compound::Number { .. } => unreachable!(),
}
Ok(())
}
}
@ -663,30 +697,33 @@ where
#[inline]
fn end(self) -> Result<()> {
match self.state {
State::Empty => {}
_ => {
match self {
Compound::Map { ser, state } => {
match state {
State::Empty => {}
_ => {
try!(
ser.formatter
.end_array(&mut ser.writer)
.map_err(Error::io)
)
}
}
try!(
self.ser
.formatter
.end_array(&mut self.ser.writer)
.map_err(Error::io)
)
}
ser.formatter
.end_object_value(&mut ser.writer)
.map_err(Error::io)
);
try!(
ser.formatter
.end_object(&mut ser.writer)
.map_err(Error::io)
);
Ok(())
},
#[cfg(feature = "arbitrary_precision")]
Compound::Number { .. } => unreachable!(),
}
try!(
self.ser
.formatter
.end_object_value(&mut self.ser.writer)
.map_err(Error::io)
);
try!(
self.ser
.formatter
.end_object(&mut self.ser.writer)
.map_err(Error::io)
);
Ok(())
}
}
@ -703,23 +740,27 @@ where
where
T: ser::Serialize,
{
try!(
self.ser
.formatter
.begin_object_key(&mut self.ser.writer, self.state == State::First)
.map_err(Error::io)
);
self.state = State::Rest;
match *self {
Compound::Map { ref mut ser, ref mut state } => {
try!(
ser.formatter
.begin_object_key(&mut ser.writer, *state == State::First)
.map_err(Error::io)
);
*state = State::Rest;
try!(key.serialize(MapKeySerializer { ser: self.ser }));
try!(key.serialize(MapKeySerializer { ser: *ser }));
try!(
self.ser
.formatter
.end_object_key(&mut self.ser.writer)
.map_err(Error::io)
);
Ok(())
try!(
ser.formatter
.end_object_key(&mut ser.writer)
.map_err(Error::io)
);
Ok(())
},
#[cfg(feature = "arbitrary_precision")]
Compound::Number { .. } => unreachable!(),
}
}
#[inline]
@ -727,36 +768,45 @@ where
where
T: ser::Serialize,
{
try!(
self.ser
.formatter
.begin_object_value(&mut self.ser.writer)
.map_err(Error::io)
);
try!(value.serialize(&mut *self.ser));
try!(
self.ser
.formatter
.end_object_value(&mut self.ser.writer)
.map_err(Error::io)
);
Ok(())
match *self {
Compound::Map { ref mut ser, .. } => {
try!(
ser.formatter
.begin_object_value(&mut ser.writer)
.map_err(Error::io)
);
try!(value.serialize(&mut **ser));
try!(
ser.formatter
.end_object_value(&mut ser.writer)
.map_err(Error::io)
);
Ok(())
},
#[cfg(feature = "arbitrary_precision")]
Compound::Number { .. } => unreachable!(),
}
}
#[inline]
fn end(self) -> Result<()> {
match self.state {
State::Empty => {}
_ => {
try!(
self.ser
.formatter
.end_object(&mut self.ser.writer)
.map_err(Error::io)
)
}
match self {
Compound::Map { ser, state } => {
match state {
State::Empty => {}
_ => {
try!(
ser.formatter
.end_object(&mut ser.writer)
.map_err(Error::io)
)
}
}
Ok(())
},
#[cfg(feature = "arbitrary_precision")]
Compound::Number { .. } => unreachable!(),
}
Ok(())
}
}
@ -773,13 +823,30 @@ where
where
T: ser::Serialize,
{
try!(ser::SerializeMap::serialize_key(self, key));
ser::SerializeMap::serialize_value(self, value)
match *self {
Compound::Map { .. } => {
try!(ser::SerializeMap::serialize_key(self, key));
ser::SerializeMap::serialize_value(self, value)
},
#[cfg(feature = "arbitrary_precision")]
Compound::Number { ref mut ser, .. } => {
if key == SERDE_STRUCT_FIELD_NAME {
try!(value.serialize(NumberStrEmitter(&mut *ser)));
Ok(())
} else {
Err(invalid_number())
}
},
}
}
#[inline]
fn end(self) -> Result<()> {
ser::SerializeMap::end(self)
match self {
Compound::Map { .. } => ser::SerializeMap::end(self),
#[cfg(feature = "arbitrary_precision")]
Compound::Number { .. } => Ok(()),
}
}
}
@ -796,35 +863,42 @@ where
where
T: ser::Serialize,
{
ser::SerializeStruct::serialize_field(self, key, value)
match *self {
Compound::Map { .. } => ser::SerializeStruct::serialize_field(self, key, value),
#[cfg(feature = "arbitrary_precision")]
Compound::Number { .. } => unreachable!(),
}
}
#[inline]
fn end(self) -> Result<()> {
match self.state {
State::Empty => {}
_ => {
match self {
Compound::Map { ser, state } => {
match state {
State::Empty => {}
_ => {
try!(
ser.formatter
.end_object(&mut ser.writer)
.map_err(Error::io)
)
}
}
try!(
self.ser
.formatter
.end_object(&mut self.ser.writer)
.map_err(Error::io)
)
}
ser.formatter
.end_object_value(&mut ser.writer)
.map_err(Error::io)
);
try!(
ser.formatter
.end_object(&mut ser.writer)
.map_err(Error::io)
);
Ok(())
},
#[cfg(feature = "arbitrary_precision")]
Compound::Number { .. } => unreachable!(),
}
try!(
self.ser
.formatter
.end_object_value(&mut self.ser.writer)
.map_err(Error::io)
);
try!(
self.ser
.formatter
.end_object(&mut self.ser.writer)
.map_err(Error::io)
);
Ok(())
}
}
@ -832,6 +906,11 @@ struct MapKeySerializer<'a, W: 'a, F: 'a> {
ser: &'a mut Serializer<W, F>,
}
#[cfg(feature = "arbitrary_precision")]
fn invalid_number() -> Error {
Error::syntax(ErrorCode::InvalidNumber, 0, 0)
}
fn key_must_be_a_string() -> Error {
Error::syntax(ErrorCode::KeyMustBeAString, 0, 0)
}
@ -1148,6 +1227,170 @@ where
}
}
#[cfg(feature = "arbitrary_precision")]
struct NumberStrEmitter<'a, W: 'a + io::Write, F: 'a + Formatter>(&'a mut Serializer<W, F>);
#[cfg(feature = "arbitrary_precision")]
impl<'a, W: io::Write, F: Formatter> ser::Serializer for NumberStrEmitter<'a, W, F> {
type Ok = ();
type Error = Error;
type SerializeSeq = Impossible<(), Error>;
type SerializeTuple = Impossible<(), Error>;
type SerializeTupleStruct = Impossible<(), Error>;
type SerializeTupleVariant = Impossible<(), Error>;
type SerializeMap = Impossible<(), Error>;
type SerializeStruct = Impossible<(), Error>;
type SerializeStructVariant = Impossible<(), Error>;
fn serialize_bool(self, _v: bool) -> Result<Self::Ok> {
Err(invalid_number())
}
fn serialize_i8(self, _v: i8) -> Result<Self::Ok> {
Err(invalid_number())
}
fn serialize_i16(self, _v: i16) -> Result<Self::Ok> {
Err(invalid_number())
}
fn serialize_i32(self, _v: i32) -> Result<Self::Ok> {
Err(invalid_number())
}
fn serialize_i64(self, _v: i64) -> Result<Self::Ok> {
Err(invalid_number())
}
fn serialize_u8(self, _v: u8) -> Result<Self::Ok> {
Err(invalid_number())
}
fn serialize_u16(self, _v: u16) -> Result<Self::Ok> {
Err(invalid_number())
}
fn serialize_u32(self, _v: u32) -> Result<Self::Ok> {
Err(invalid_number())
}
fn serialize_u64(self, _v: u64) -> Result<Self::Ok> {
Err(invalid_number())
}
fn serialize_f32(self, _v: f32) -> Result<Self::Ok> {
Err(invalid_number())
}
fn serialize_f64(self, _v: f64) -> Result<Self::Ok> {
Err(invalid_number())
}
fn serialize_char(self, _v: char) -> Result<Self::Ok> {
Err(invalid_number())
}
fn serialize_str(self, value: &str) -> Result<Self::Ok> {
let NumberStrEmitter(serializer) = self;
serializer.formatter.write_number_str(&mut serializer.writer, value)
.map_err(Error::io)
}
fn serialize_bytes(self, _value: &[u8]) -> Result<Self::Ok> {
Err(invalid_number())
}
fn serialize_none(self) -> Result<Self::Ok> {
Err(invalid_number())
}
fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<Self::Ok>
where T: Serialize
{
Err(invalid_number())
}
fn serialize_unit(self) -> Result<Self::Ok> {
Err(invalid_number())
}
fn serialize_unit_struct(self,
_name: &'static str)
-> Result<Self::Ok> {
Err(invalid_number())
}
fn serialize_unit_variant(self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str)
-> Result<Self::Ok> {
Err(invalid_number())
}
fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, _value: &T)
-> Result<Self::Ok>
where T: Serialize,
{
Err(invalid_number())
}
fn serialize_newtype_variant<T: ?Sized>(self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_value: &T)
-> Result<Self::Ok>
where T: Serialize,
{
Err(invalid_number())
}
fn serialize_seq(self, _len: Option<usize>)
-> Result<Self::SerializeSeq> {
Err(invalid_number())
}
fn serialize_tuple(self, _len: usize)
-> Result<Self::SerializeTuple> {
Err(invalid_number())
}
fn serialize_tuple_struct(self, _name: &'static str, _len: usize)
-> Result<Self::SerializeTupleStruct> {
Err(invalid_number())
}
fn serialize_tuple_variant(self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize)
-> Result<Self::SerializeTupleVariant> {
Err(invalid_number())
}
fn serialize_map(self, _len: Option<usize>)
-> Result<Self::SerializeMap> {
Err(invalid_number())
}
fn serialize_struct(self, _name: &'static str, _len: usize)
-> Result<Self::SerializeStruct> {
Err(invalid_number())
}
fn serialize_struct_variant(self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize)
-> Result<Self::SerializeStructVariant> {
Err(invalid_number())
}
}
/// Represents a character escape code in a type-safe manner.
pub enum CharEscape {
/// An escaped quote `"`
@ -1304,6 +1547,14 @@ pub trait Formatter {
dtoa::write(writer, value).map(|_| ())
}
/// Writes a number that has already been rendered to a string.
#[inline]
fn write_number_str<W: ?Sized>(&mut self, writer: &mut W, value: &str) -> io::Result<()>
where W: io::Write
{
writer.write_all(value.as_bytes())
}
/// Called before each series of `write_string_fragment` and
/// `write_char_escape`. Writes a `"` to the specified writer.
#[inline]

View File

@ -32,6 +32,12 @@ use map::Map;
use number::Number;
use value::Value;
#[cfg(feature = "arbitrary_precision")]
use serde::de;
#[cfg(feature = "arbitrary_precision")]
use number::{NumberFromString, SERDE_STRUCT_FIELD_NAME};
impl<'de> Deserialize<'de> for Value {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Value, D::Error>
@ -112,6 +118,7 @@ impl<'de> Deserialize<'de> for Value {
Ok(Value::Array(vec))
}
#[cfg(not(feature = "arbitrary_precision"))]
fn visit_map<V>(self, mut visitor: V) -> Result<Value, V::Error>
where
V: MapAccess<'de>,
@ -124,6 +131,34 @@ impl<'de> Deserialize<'de> for Value {
Ok(Value::Object(values))
}
#[cfg(feature = "arbitrary_precision")]
fn visit_map<V>(self, mut visitor: V) -> Result<Value, V::Error>
where
V: MapAccess<'de>,
{
let mut key = String::new();
let number = visitor.next_key_seed(NumberOrObject {
key: &mut key,
})?;
match number {
Some(true) => {
let number: NumberFromString = visitor.next_value()?;
return Ok(Value::Number(number.value))
}
None => return Ok(Value::Object(Map::new())),
Some(false) => {}
}
let mut values = Map::new();
values.insert(key, try!(visitor.next_value()));
while let Some((key, value)) = try!(visitor.next_entry()) {
values.insert(key, value);
}
Ok(Value::Object(values))
}
}
deserializer.deserialize_any(ValueVisitor)
@ -199,6 +234,29 @@ impl str::FromStr for Value {
}
}
macro_rules! deserialize_prim_number {
($method:ident) => {
#[cfg(not(feature = "arbitrary_precision"))]
fn $method<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
self.deserialize_any(visitor)
}
#[cfg(feature = "arbitrary_precision")]
fn $method<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
match self {
Value::Number(n) => n.$method(visitor),
_ => self.deserialize_any(visitor),
}
}
}
}
impl<'de> serde::Deserializer<'de> for Value {
type Error = Error;
@ -237,6 +295,17 @@ impl<'de> serde::Deserializer<'de> for Value {
}
}
deserialize_prim_number!(deserialize_i8);
deserialize_prim_number!(deserialize_i16);
deserialize_prim_number!(deserialize_i32);
deserialize_prim_number!(deserialize_i64);
deserialize_prim_number!(deserialize_u8);
deserialize_prim_number!(deserialize_u16);
deserialize_prim_number!(deserialize_u32);
deserialize_prim_number!(deserialize_u64);
deserialize_prim_number!(deserialize_f32);
deserialize_prim_number!(deserialize_f64);
#[inline]
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
where
@ -305,9 +374,8 @@ impl<'de> serde::Deserializer<'de> for Value {
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
byte_buf unit unit_struct seq tuple tuple_struct map struct identifier
ignored_any
bool char str string bytes byte_buf unit unit_struct seq tuple
tuple_struct map struct identifier ignored_any
}
}
@ -512,6 +580,29 @@ impl<'de> serde::Deserializer<'de> for MapDeserializer {
}
}
macro_rules! deserialize_value_ref_number {
($method:ident) => {
#[cfg(not(feature = "arbitrary_precision"))]
fn $method<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
self.deserialize_any(visitor)
}
#[cfg(feature = "arbitrary_precision")]
fn $method<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
match *self {
Value::Number(ref n) => n.$method(visitor),
_ => self.deserialize_any(visitor),
}
}
}
}
impl<'de> serde::Deserializer<'de> for &'de Value {
type Error = Error;
@ -549,6 +640,17 @@ impl<'de> serde::Deserializer<'de> for &'de Value {
}
}
deserialize_value_ref_number!(deserialize_i8);
deserialize_value_ref_number!(deserialize_i16);
deserialize_value_ref_number!(deserialize_i32);
deserialize_value_ref_number!(deserialize_i64);
deserialize_value_ref_number!(deserialize_u8);
deserialize_value_ref_number!(deserialize_u16);
deserialize_value_ref_number!(deserialize_u32);
deserialize_value_ref_number!(deserialize_u64);
deserialize_value_ref_number!(deserialize_f32);
deserialize_value_ref_number!(deserialize_f64);
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
@ -615,9 +717,8 @@ impl<'de> serde::Deserializer<'de> for &'de Value {
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
byte_buf unit unit_struct seq tuple tuple_struct map struct identifier
ignored_any
bool char str string bytes byte_buf unit unit_struct seq tuple
tuple_struct map struct identifier ignored_any
}
}
@ -827,8 +928,8 @@ struct MapKeyDeserializer<'de> {
}
macro_rules! deserialize_integer_key {
($deserialize:ident => $visit:ident) => {
fn $deserialize<V>(self, visitor: V) -> Result<V::Value, Error>
($method:ident => $visit:ident) => {
fn $method<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
@ -895,6 +996,56 @@ impl<'de> serde::Deserializer<'de> for MapKeyDeserializer<'de> {
}
}
#[cfg(feature = "arbitrary_precision")]
struct NumberOrObject<'a> {
key: &'a mut String,
}
#[cfg(feature = "arbitrary_precision")]
impl<'a, 'de> DeserializeSeed<'de> for NumberOrObject<'a> {
type Value = bool;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>
{
deserializer.deserialize_any(self)
}
}
#[cfg(feature = "arbitrary_precision")]
impl<'a, 'de> Visitor<'de> for NumberOrObject<'a> {
type Value = bool;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string key")
}
fn visit_str<E>(self, s: &str) -> Result<bool, E>
where
E: de::Error,
{
if s == SERDE_STRUCT_FIELD_NAME {
Ok(true)
} else {
self.key.push_str(s);
Ok(false)
}
}
fn visit_string<E>(self, s: String) -> Result<bool, E>
where
E: de::Error,
{
if s == SERDE_STRUCT_FIELD_NAME {
Ok(true)
} else {
*self.key = s;
Ok(false)
}
}
}
impl Value {
fn unexpected(&self) -> Unexpected {
match *self {

View File

@ -7,12 +7,19 @@
// except according to those terms.
use serde::{self, Serialize};
use serde::ser::{Impossible};
use error::{Error, ErrorCode};
use map::Map;
use number::Number;
use value::{Value, to_value};
#[cfg(feature = "arbitrary_precision")]
use serde::ser;
#[cfg(feature = "arbitrary_precision")]
use number::{SERDE_STRUCT_NAME, SERDE_STRUCT_FIELD_NAME};
impl Serialize for Value {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@ -216,13 +223,14 @@ impl serde::Serializer for Serializer {
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Error> {
Ok(
SerializeMap {
SerializeMap::Map {
map: Map::new(),
next_key: None,
},
)
}
#[cfg(not(feature = "arbitrary_precision"))]
fn serialize_struct(
self,
_name: &'static str,
@ -231,6 +239,19 @@ impl serde::Serializer for Serializer {
self.serialize_map(Some(len))
}
#[cfg(feature = "arbitrary_precision")]
fn serialize_struct(
self,
name: &'static str,
len: usize,
) -> Result<Self::SerializeStruct, Error> {
if name == SERDE_STRUCT_NAME {
Ok(SerializeMap::Number { out_value: None })
} else {
self.serialize_map(Some(len))
}
}
fn serialize_struct_variant(
self,
_name: &'static str,
@ -247,24 +268,26 @@ impl serde::Serializer for Serializer {
}
}
#[doc(hidden)]
pub struct SerializeVec {
vec: Vec<Value>,
}
#[doc(hidden)]
pub struct SerializeTupleVariant {
name: String,
vec: Vec<Value>,
}
#[doc(hidden)]
pub struct SerializeMap {
map: Map<String, Value>,
next_key: Option<String>,
pub enum SerializeMap {
Map {
map: Map<String, Value>,
next_key: Option<String>,
},
#[cfg(feature = "arbitrary_precision")]
Number {
out_value: Option<Value>
},
}
#[doc(hidden)]
pub struct SerializeStructVariant {
name: String,
map: Map<String, Value>,
@ -348,34 +371,221 @@ impl serde::ser::SerializeMap for SerializeMap {
where
T: Serialize,
{
match try!(to_value(&key)) {
Value::String(s) => self.next_key = Some(s),
Value::Number(n) => {
if n.is_u64() || n.is_i64() {
self.next_key = Some(n.to_string())
} else {
return Err(Error::syntax(ErrorCode::KeyMustBeAString, 0, 0));
}
}
_ => return Err(Error::syntax(ErrorCode::KeyMustBeAString, 0, 0)),
};
Ok(())
match *self {
SerializeMap::Map { ref mut next_key, .. } => {
*next_key = Some(try!(key.serialize(MapKeySerializer)));
Ok(())
},
#[cfg(feature = "arbitrary_precision")]
SerializeMap::Number { .. } => unreachable!(),
}
}
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
where
T: Serialize,
{
let key = self.next_key.take();
// Panic because this indicates a bug in the program rather than an
// expected failure.
let key = key.expect("serialize_value called before serialize_key");
self.map.insert(key, try!(to_value(&value)));
Ok(())
match *self {
SerializeMap::Map { ref mut map, ref mut next_key } => {
let key = next_key.take();
// Panic because this indicates a bug in the program rather than an
// expected failure.
let key = key.expect("serialize_value called before serialize_key");
map.insert(key, try!(to_value(&value)));
Ok(())
},
#[cfg(feature = "arbitrary_precision")]
SerializeMap::Number { .. } => unreachable!(),
}
}
fn end(self) -> Result<Value, Error> {
Ok(Value::Object(self.map))
match self {
SerializeMap::Map { map, .. } => Ok(Value::Object(map)),
#[cfg(feature = "arbitrary_precision")]
SerializeMap::Number { .. } => unreachable!(),
}
}
}
struct MapKeySerializer;
fn key_must_be_a_string() -> Error {
Error::syntax(ErrorCode::KeyMustBeAString, 0, 0)
}
impl serde::Serializer for MapKeySerializer {
type Ok = String;
type Error = Error;
type SerializeSeq = Impossible<String, Error>;
type SerializeTuple = Impossible<String, Error>;
type SerializeTupleStruct = Impossible<String, Error>;
type SerializeTupleVariant = Impossible<String, Error>;
type SerializeMap = Impossible<String, Error>;
type SerializeStruct = Impossible<String, Error>;
type SerializeStructVariant = Impossible<String, Error>;
#[inline]
fn serialize_unit_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str
) -> Result<Self::Ok, Self::Error> {
Ok(variant.to_owned())
}
#[inline]
fn serialize_newtype_struct<T: ?Sized>(
self,
_name: &'static str,
value: &T
) -> Result<Self::Ok, Self::Error>
where T: Serialize,
{
value.serialize(self)
}
fn serialize_bool(self, _value: bool) -> Result<Self::Ok, Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_i8(self, value: i8) -> Result<Self::Ok, Self::Error> {
Ok(value.to_string())
}
fn serialize_i16(self, value: i16) -> Result<Self::Ok, Self::Error> {
Ok(value.to_string())
}
fn serialize_i32(self, value: i32) -> Result<Self::Ok, Self::Error> {
Ok(value.to_string())
}
fn serialize_i64(self, value: i64) -> Result<Self::Ok, Self::Error> {
Ok(value.to_string())
}
fn serialize_u8(self, value: u8) -> Result<Self::Ok, Self::Error> {
Ok(value.to_string())
}
fn serialize_u16(self, value: u16) -> Result<Self::Ok, Self::Error> {
Ok(value.to_string())
}
fn serialize_u32(self, value: u32) -> Result<Self::Ok, Self::Error> {
Ok(value.to_string())
}
fn serialize_u64(self, value: u64) -> Result<Self::Ok, Self::Error> {
Ok(value.to_string())
}
fn serialize_f32(self, _value: f32) -> Result<Self::Ok, Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_f64(self, _value: f64) -> Result<Self::Ok, Self::Error> {
Err(key_must_be_a_string())
}
#[inline]
fn serialize_char(self, value: char) -> Result<Self::Ok, Self::Error> {
Ok({
let mut s = String::new();
s.push(value);
s
})
}
#[inline]
fn serialize_str(self, value: &str) -> Result<Self::Ok, Self::Error> {
Ok(value.to_owned())
}
fn serialize_bytes(self, _value: &[u8]) -> Result<Self::Ok, Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_newtype_variant<T: ?Sized>(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_value: &T
) -> Result<Self::Ok, Self::Error>
where T: Serialize,
{
Err(key_must_be_a_string())
}
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<Self::Ok, Self::Error>
where
T: Serialize,
{
Err(key_must_be_a_string())
}
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_tuple_struct(
self,
_name: &'static str,
_len: usize
) -> Result<Self::SerializeTupleStruct, Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_tuple_variant(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize
) -> Result<Self::SerializeTupleVariant, Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_struct(
self,
_name: &'static str,
_len: usize
) -> Result<Self::SerializeStruct, Self::Error> {
Err(key_must_be_a_string())
}
fn serialize_struct_variant(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize
) -> Result<Self::SerializeStructVariant, Self::Error> {
Err(key_must_be_a_string())
}
}
@ -387,12 +597,29 @@ impl serde::ser::SerializeStruct for SerializeMap {
where
T: Serialize,
{
try!(serde::ser::SerializeMap::serialize_key(self, key));
serde::ser::SerializeMap::serialize_value(self, value)
match *self {
SerializeMap::Map { .. } => {
try!(serde::ser::SerializeMap::serialize_key(self, key));
serde::ser::SerializeMap::serialize_value(self, value)
},
#[cfg(feature = "arbitrary_precision")]
SerializeMap::Number { ref mut out_value } => {
if key == SERDE_STRUCT_FIELD_NAME {
*out_value = Some(value.serialize(NumberValueEmitter)?);
Ok(())
} else {
Err(invalid_number())
}
},
}
}
fn end(self) -> Result<Value, Error> {
serde::ser::SerializeMap::end(self)
match self {
SerializeMap::Map { .. } => serde::ser::SerializeMap::end(self),
#[cfg(feature = "arbitrary_precision")]
SerializeMap::Number { out_value, .. } => Ok(out_value.expect("number value was not emitted")),
}
}
}
@ -417,3 +644,174 @@ impl serde::ser::SerializeStructVariant for SerializeStructVariant {
Ok(Value::Object(object))
}
}
#[cfg(feature = "arbitrary_precision")]
struct NumberValueEmitter;
#[cfg(feature = "arbitrary_precision")]
fn invalid_number() -> Error {
Error::syntax(ErrorCode::InvalidNumber, 0, 0)
}
#[cfg(feature = "arbitrary_precision")]
impl ser::Serializer for NumberValueEmitter {
type Ok = Value;
type Error = Error;
type SerializeSeq = Impossible<Value, Error>;
type SerializeTuple = Impossible<Value, Error>;
type SerializeTupleStruct = Impossible<Value, Error>;
type SerializeTupleVariant = Impossible<Value, Error>;
type SerializeMap = Impossible<Value, Error>;
type SerializeStruct = Impossible<Value, Error>;
type SerializeStructVariant = Impossible<Value, Error>;
fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> {
Err(invalid_number())
}
fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> {
Err(invalid_number())
}
fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> {
Err(invalid_number())
}
fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> {
Err(invalid_number())
}
fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> {
Err(invalid_number())
}
fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> {
Err(invalid_number())
}
fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> {
Err(invalid_number())
}
fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> {
Err(invalid_number())
}
fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> {
Err(invalid_number())
}
fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
Err(invalid_number())
}
fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
Err(invalid_number())
}
fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> {
Err(invalid_number())
}
fn serialize_str(self, value: &str) -> Result<Self::Ok, Self::Error> {
let n = try!(value.to_owned().parse());
Ok(Value::Number(n))
}
fn serialize_bytes(self, _value: &[u8]) -> Result<Self::Ok, Self::Error> {
Err(invalid_number())
}
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
Err(invalid_number())
}
fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<Self::Ok, Self::Error>
where
T: Serialize,
{
Err(invalid_number())
}
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
Err(invalid_number())
}
fn serialize_unit_struct(self,
_name: &'static str)
-> Result<Self::Ok, Self::Error> {
Err(invalid_number())
}
fn serialize_unit_variant(self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str)
-> Result<Self::Ok, Self::Error> {
Err(invalid_number())
}
fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, _value: &T)
-> Result<Self::Ok, Self::Error>
where
T: Serialize,
{
Err(invalid_number())
}
fn serialize_newtype_variant<T: ?Sized>(self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_value: &T)
-> Result<Self::Ok, Self::Error>
where
T: Serialize,
{
Err(invalid_number())
}
fn serialize_seq(self, _len: Option<usize>)
-> Result<Self::SerializeSeq, Self::Error> {
Err(invalid_number())
}
fn serialize_tuple(self, _len: usize)
-> Result<Self::SerializeTuple, Self::Error> {
Err(invalid_number())
}
fn serialize_tuple_struct(self, _name: &'static str, _len: usize)
-> Result<Self::SerializeTupleStruct, Self::Error> {
Err(invalid_number())
}
fn serialize_tuple_variant(self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize)
-> Result<Self::SerializeTupleVariant, Self::Error> {
Err(invalid_number())
}
fn serialize_map(self, _len: Option<usize>)
-> Result<Self::SerializeMap, Self::Error> {
Err(invalid_number())
}
fn serialize_struct(self, _name: &'static str, _len: usize)
-> Result<Self::SerializeStruct, Self::Error> {
Err(invalid_number())
}
fn serialize_struct_variant(self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize)
-> Result<Self::SerializeStructVariant, Self::Error> {
Err(invalid_number())
}
}

View File

@ -6,5 +6,8 @@ publish = false
[workspace]
[features]
arbitrary_precision = ["serde_json/arbitrary_precision"]
[dependencies]
serde_json = { path = "../.." }

View File

@ -32,6 +32,8 @@ use std::{i8, i16, i32, i64};
use std::io;
use std::iter;
use std::marker::PhantomData;
use std::str::FromStr;
use std::string::ToString;
use std::{u8, u16, u32, u64};
use serde::de::{self, Deserialize, IgnoredAny};
@ -39,8 +41,9 @@ use serde::ser::{self, Serialize, Serializer};
use serde_bytes::{ByteBuf, Bytes};
use serde_json::{Deserializer, Value, from_reader, from_slice, from_str, from_value,
to_string, to_string_pretty, to_value, to_vec, to_writer};
use serde_json::{Deserializer, Number, Value, from_reader, from_slice, from_str,
from_value, to_string, to_string_pretty, to_value, to_vec,
to_writer};
macro_rules! treemap {
() => {
@ -568,6 +571,17 @@ fn test_write_newtype_struct() {
test_encode_ok(&[(outer, r#"{"outer":{"inner":123}}"#)]);
}
#[test]
fn test_deserialize_number_to_untagged_enum() {
#[derive(Eq, PartialEq, Deserialize, Debug)]
#[serde(untagged)]
enum E {
N(i64),
}
assert_eq!(E::N(0), E::deserialize(Number::from(0)).unwrap());
}
fn test_parse_ok<T>(tests: Vec<(&str, T)>)
where
T: Clone + Debug + PartialEq + ser::Serialize + de::DeserializeOwned,
@ -644,6 +658,16 @@ where
}
}
fn test_fromstr_parse_err<T>(errors: &[(&str, &'static str)])
where
T: Debug + PartialEq + FromStr, <T as FromStr>::Err: ToString
{
for &(s, err) in errors {
let actual = s.parse::<T>().unwrap_err().to_string();
assert_eq!(actual, err, "unexpected parsing error");
}
}
#[test]
fn test_parse_null() {
test_parse_err::<()>(
@ -689,7 +713,11 @@ fn test_parse_char() {
test_parse_err::<char>(
&[
("\"ab\"", "invalid value: string \"ab\", expected a character at line 1 column 4"),
("10", "invalid type: integer `10`, expected a character at line 1 column 2"),
("10", if cfg!(feature = "arbitrary_precision") {
"invalid type: number, expected a character at line 1 column 2"
} else {
"invalid type: integer `10`, expected a character at line 1 column 2"
}),
],
);
@ -795,14 +823,19 @@ fn test_parse_negative_zero() {
#[test]
fn test_parse_f64() {
test_parse_ok(
vec![
test_parse_ok(vec![
("0.0", 0.0f64),
("3.0", 3.0f64),
("3.00", 3.0f64),
("3.1", 3.1),
("-1.2", -1.2),
("0.4", 0.4),
]);
#[cfg(not(feature = "arbitrary_precision"))]
test_parse_ok(vec![
// With arbitrary-precision enabled, this parses as Number{"3.00"}
// but the float is Number{"3.0"}
("3.00", 3.0f64),
("0.4e5", 0.4e5),
("0.4e+5", 0.4e5),
("0.4e15", 0.4e15),
@ -814,9 +847,9 @@ fn test_parse_f64() {
("0.00e00", 0.0),
("0.00e+00", 0.0),
("0.00e-00", 0.0),
(&format!("{:?}", (i64::MIN as f64) - 1.0), (i64::MIN as f64) - 1.0),
(&format!("{:?}", (u64::MAX as f64) + 1.0), (u64::MAX as f64) + 1.0),
(&format!("{:?}", f64::EPSILON), f64::EPSILON),
(&format!("{}", (i64::MIN as f64) - 1.0), (i64::MIN as f64) - 1.0),
(&format!("{}", (u64::MAX as f64) + 1.0), (u64::MAX as f64) + 1.0),
(&format!("{}", f64::EPSILON), f64::EPSILON),
("0.0000000000000000000000000000000000000000000000000123e50", 1.23),
("100e-777777777777777777777777777", 0.0),
("1010101010101010101010101010101010101010", 10101010101010101010e20),
@ -846,8 +879,60 @@ fn test_parse_f64() {
000000000000000000000000000000000000000000000000000000000000\
000000000000000000000000000000000000000000000000000000000000\
000000000000000000e-10", 1e308),
],
]);
}
#[test]
fn test_serialize_char() {
let value = json!(({
let mut map = BTreeMap::new();
map.insert('c', ());
map
}));
assert_eq!(&Value::Null, value.get("c").unwrap());
}
#[cfg(feature = "arbitrary_precision")]
#[test]
fn test_malicious_number() {
#[derive(Serialize)]
#[serde(rename = "$__serde_private_Number")]
struct S {
#[serde(rename = "$__serde_private_number")]
f: &'static str,
}
let actual = serde_json::to_value(&S { f: "not a number" }).unwrap_err().to_string();
assert_eq!(actual, "invalid number at line 1 column 1");
}
#[test]
fn test_parse_number() {
test_parse_ok(vec![
("0.0", Number::from_f64(0.0f64).unwrap()),
("3.0", Number::from_f64(3.0f64).unwrap()),
("3.1", Number::from_f64(3.1).unwrap()),
("-1.2", Number::from_f64(-1.2).unwrap()),
("0.4", Number::from_f64(0.4).unwrap()),
]);
test_fromstr_parse_err::<Number>(
&[
(" 1.0", "invalid number at line 1 column 1"),
("1.0 ", "invalid number at line 1 column 4"),
("\t1.0", "invalid number at line 1 column 1"),
("1.0\t", "invalid number at line 1 column 4"),
]
);
#[cfg(feature = "arbitrary_precision")]
test_parse_ok(vec![
("1e999", Number::from_string_unchecked("1e999".to_owned())),
("-1e999", Number::from_string_unchecked("-1e999".to_owned())),
("1e-999", Number::from_string_unchecked("1e-999".to_owned())),
("2.3e999", Number::from_string_unchecked("2.3e999".to_owned())),
("-2.3e999", Number::from_string_unchecked("-2.3e999".to_owned())),
]);
}
#[test]
@ -1020,7 +1105,11 @@ fn test_parse_object() {
fn test_parse_struct() {
test_parse_err::<Outer>(
&[
("5", "invalid type: integer `5`, expected struct Outer at line 1 column 1"),
("5", if cfg!(feature = "arbitrary_precision") {
"invalid type: number, expected struct Outer at line 1 column 1"
} else {
"invalid type: integer `5`, expected struct Outer at line 1 column 1"
}),
("\"hello\"", "invalid type: string \"hello\", expected struct Outer at line 1 column 7"),
("{\"inner\": true}",
"invalid type: boolean `true`, expected a sequence at line 1 column 14"),
@ -1060,8 +1149,7 @@ fn test_parse_struct() {
[ null, 2, [\"abc\", \"xyz\"] ]
]
]",
)
.unwrap();
).unwrap();
assert_eq!(
v,

View File

@ -36,10 +36,12 @@ else
(cd "$DIR/tests/deps" && channel build)
channel test
channel test --features preserve_order
channel test --features arbitrary_precision
for CHANNEL in stable 1.15.0 beta; do
channel clean
channel build
channel build --features preserve_order
channel build --features arbitrary_precision
done
fi