Skip to content

Commit

Permalink
Merge pull request #942 from serde-rs/integer128
Browse files Browse the repository at this point in the history
Assume serde_if_integer128 is true
  • Loading branch information
dtolnay authored Oct 19, 2022
2 parents ec0456a + 37e76e0 commit 46c9778
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 197 deletions.
145 changes: 67 additions & 78 deletions src/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use core::marker::PhantomData;
use core::result;
use core::str::FromStr;
use serde::de::{self, Expected, Unexpected};
use serde::{forward_to_deserialize_any, serde_if_integer128};
use serde::forward_to_deserialize_any;

#[cfg(feature = "arbitrary_precision")]
use crate::number::NumberDeserializer;
Expand Down Expand Up @@ -335,31 +335,25 @@ impl<'de, R: Read<'de>> Deserializer<R> {
}
}

serde_if_integer128! {
fn scan_integer128(&mut self, buf: &mut String) -> Result<()> {
match tri!(self.next_char_or_null()) {
b'0' => {
buf.push('0');
// There can be only one leading '0'.
match tri!(self.peek_or_null()) {
b'0'..=b'9' => {
Err(self.peek_error(ErrorCode::InvalidNumber))
}
_ => Ok(()),
}
fn scan_integer128(&mut self, buf: &mut String) -> Result<()> {
match tri!(self.next_char_or_null()) {
b'0' => {
buf.push('0');
// There can be only one leading '0'.
match tri!(self.peek_or_null()) {
b'0'..=b'9' => Err(self.peek_error(ErrorCode::InvalidNumber)),
_ => Ok(()),
}
c @ b'1'..=b'9' => {
}
c @ b'1'..=b'9' => {
buf.push(c as char);
while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) {
self.eat_char();
buf.push(c as char);
while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) {
self.eat_char();
buf.push(c as char);
}
Ok(())
}
_ => {
Err(self.error(ErrorCode::InvalidNumber))
}
Ok(())
}
_ => Err(self.error(ErrorCode::InvalidNumber)),
}
}

Expand Down Expand Up @@ -1437,67 +1431,65 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer<R> {
val
}

serde_if_integer128! {
fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
let mut buf = String::new();

match tri!(self.parse_whitespace()) {
Some(b'-') => {
self.eat_char();
buf.push('-');
}
Some(_) => {}
None => {
return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
}
};
fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
let mut buf = String::new();

tri!(self.scan_integer128(&mut buf));
match tri!(self.parse_whitespace()) {
Some(b'-') => {
self.eat_char();
buf.push('-');
}
Some(_) => {}
None => {
return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
}
};

let value = match buf.parse() {
Ok(int) => visitor.visit_i128(int),
Err(_) => {
return Err(self.error(ErrorCode::NumberOutOfRange));
}
};
tri!(self.scan_integer128(&mut buf));

match value {
Ok(value) => Ok(value),
Err(err) => Err(self.fix_position(err)),
let value = match buf.parse() {
Ok(int) => visitor.visit_i128(int),
Err(_) => {
return Err(self.error(ErrorCode::NumberOutOfRange));
}
};

match value {
Ok(value) => Ok(value),
Err(err) => Err(self.fix_position(err)),
}
}

fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
match tri!(self.parse_whitespace()) {
Some(b'-') => {
return Err(self.peek_error(ErrorCode::NumberOutOfRange));
}
Some(_) => {}
None => {
return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
}
fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value>
where
V: de::Visitor<'de>,
{
match tri!(self.parse_whitespace()) {
Some(b'-') => {
return Err(self.peek_error(ErrorCode::NumberOutOfRange));
}
Some(_) => {}
None => {
return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
}
}

let mut buf = String::new();
tri!(self.scan_integer128(&mut buf));

let value = match buf.parse() {
Ok(int) => visitor.visit_u128(int),
Err(_) => {
return Err(self.error(ErrorCode::NumberOutOfRange));
}
};
let mut buf = String::new();
tri!(self.scan_integer128(&mut buf));

match value {
Ok(value) => Ok(value),
Err(err) => Err(self.fix_position(err)),
let value = match buf.parse() {
Ok(int) => visitor.visit_u128(int),
Err(_) => {
return Err(self.error(ErrorCode::NumberOutOfRange));
}
};

match value {
Ok(value) => Ok(value),
Err(err) => Err(self.fix_position(err)),
}
}

Expand Down Expand Up @@ -2164,15 +2156,12 @@ where
deserialize_integer_key!(deserialize_i16 => visit_i16);
deserialize_integer_key!(deserialize_i32 => visit_i32);
deserialize_integer_key!(deserialize_i64 => visit_i64);
deserialize_integer_key!(deserialize_i128 => visit_i128);
deserialize_integer_key!(deserialize_u8 => visit_u8);
deserialize_integer_key!(deserialize_u16 => visit_u16);
deserialize_integer_key!(deserialize_u32 => visit_u32);
deserialize_integer_key!(deserialize_u64 => visit_u64);

serde_if_integer128! {
deserialize_integer_key!(deserialize_i128 => visit_i128);
deserialize_integer_key!(deserialize_u128 => visit_u128);
}
deserialize_integer_key!(deserialize_u128 => visit_u128);

#[inline]
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
Expand Down
26 changes: 8 additions & 18 deletions src/number.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@ use core::hash::{Hash, Hasher};
use serde::de::{self, Unexpected, Visitor};
#[cfg(feature = "arbitrary_precision")]
use serde::de::{IntoDeserializer, MapAccess};
use serde::{
forward_to_deserialize_any, serde_if_integer128, Deserialize, Deserializer, Serialize,
Serializer,
};
use serde::{forward_to_deserialize_any, Deserialize, Deserializer, Serialize, Serializer};

#[cfg(feature = "arbitrary_precision")]
pub(crate) const TOKEN: &str = "$serde_json::private::Number";
Expand Down Expand Up @@ -540,18 +537,15 @@ impl<'de> Deserializer<'de> for Number {
deserialize_number!(deserialize_i16 => visit_i16);
deserialize_number!(deserialize_i32 => visit_i32);
deserialize_number!(deserialize_i64 => visit_i64);
deserialize_number!(deserialize_i128 => visit_i128);
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_u128 => visit_u128);
deserialize_number!(deserialize_f32 => visit_f32);
deserialize_number!(deserialize_f64 => visit_f64);

serde_if_integer128! {
deserialize_number!(deserialize_i128 => visit_i128);
deserialize_number!(deserialize_u128 => visit_u128);
}

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
Expand All @@ -568,18 +562,15 @@ impl<'de, 'a> Deserializer<'de> for &'a Number {
deserialize_number!(deserialize_i16 => visit_i16);
deserialize_number!(deserialize_i32 => visit_i32);
deserialize_number!(deserialize_i64 => visit_i64);
deserialize_number!(deserialize_i128 => visit_i128);
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_u128 => visit_u128);
deserialize_number!(deserialize_f32 => visit_f32);
deserialize_number!(deserialize_f64 => visit_f64);

serde_if_integer128! {
deserialize_number!(deserialize_i128 => visit_i128);
deserialize_number!(deserialize_u128 => visit_u128);
}

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
Expand Down Expand Up @@ -731,10 +722,9 @@ impl_from_unsigned!(u8, u16, u32, u64, usize);
impl_from_signed!(i8, i16, i32, i64, isize);

#[cfg(feature = "arbitrary_precision")]
serde_if_integer128! {
impl_from_unsigned!(u128);
impl_from_signed!(i128);
}
impl_from_unsigned!(u128);
#[cfg(feature = "arbitrary_precision")]
impl_from_signed!(i128);

impl Number {
#[cfg(not(feature = "arbitrary_precision"))]
Expand Down
Loading

0 comments on commit 46c9778

Please sign in to comment.