Skip to content

Commit

Permalink
Merge pull request #2167 from serde-rs/error128
Browse files Browse the repository at this point in the history
Render 128-bit integer value into Visitor errors
  • Loading branch information
dtolnay committed Jan 25, 2022
2 parents 8932c85 + 0d71ac8 commit c3ce2c9
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 4 deletions.
30 changes: 30 additions & 0 deletions serde/src/de/format.rs
@@ -0,0 +1,30 @@
use lib::fmt::{self, Write};
use lib::str;

pub struct Buf<'a> {
bytes: &'a mut [u8],
offset: usize,
}

impl<'a> Buf<'a> {
pub fn new(bytes: &'a mut [u8]) -> Self {
Buf { bytes, offset: 0 }
}

pub fn as_str(&self) -> &str {
let slice = &self.bytes[..self.offset];
unsafe { str::from_utf8_unchecked(slice) }
}
}

impl<'a> Write for Buf<'a> {
fn write_str(&mut self, s: &str) -> fmt::Result {
if self.offset + s.len() > self.bytes.len() {
Err(fmt::Error)
} else {
self.bytes[self.offset..self.offset + s.len()].copy_from_slice(s.as_bytes());
self.offset += s.len();
Ok(())
}
}
}
14 changes: 10 additions & 4 deletions serde/src/de/mod.rs
Expand Up @@ -118,6 +118,8 @@ use lib::*;

pub mod value;

#[cfg(not(no_integer128))]
mod format;
mod ignored_any;
mod impls;
mod utf8;
Expand Down Expand Up @@ -1366,8 +1368,10 @@ pub trait Visitor<'de>: Sized {
where
E: Error,
{
let _ = v;
Err(Error::invalid_type(Unexpected::Other("i128"), &self))
let mut buf = [0u8; 58];
let mut writer = format::Buf::new(&mut buf);
fmt::Write::write_fmt(&mut writer, format_args!("integer `{}` as i128", v)).unwrap();
Err(Error::invalid_type(Unexpected::Other(writer.as_str()), &self))
}
}

Expand Down Expand Up @@ -1426,8 +1430,10 @@ pub trait Visitor<'de>: Sized {
where
E: Error,
{
let _ = v;
Err(Error::invalid_type(Unexpected::Other("u128"), &self))
let mut buf = [0u8; 57];
let mut writer = format::Buf::new(&mut buf);
fmt::Write::write_fmt(&mut writer, format_args!("integer `{}` as u128", v)).unwrap();
Err(Error::invalid_type(Unexpected::Other(writer.as_str()), &self))
}
}

Expand Down
25 changes: 25 additions & 0 deletions test_suite/tests/test_de_error.rs
@@ -1,6 +1,7 @@
#![allow(clippy::empty_enum, clippy::unreadable_literal)]
#![cfg_attr(feature = "unstable", feature(never_type))]

use serde::de::IntoDeserializer;
use serde::Deserialize;
use serde_test::{assert_de_tokens_error, Token};
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
Expand Down Expand Up @@ -185,6 +186,16 @@ fn test_i64() {
);
}

#[test]
fn test_i128() {
let deserializer = <i128 as IntoDeserializer>::into_deserializer(1);
let error = <&str>::deserialize(deserializer).unwrap_err();
assert_eq!(
error.to_string(),
"invalid type: integer `1` as i128, expected a borrowed string",
);
}

#[test]
fn test_u8() {
let test = assert_de_tokens_error::<u8>;
Expand Down Expand Up @@ -326,6 +337,13 @@ fn test_u64() {
&[Token::I64(-1)],
"invalid value: integer `-1`, expected u64",
);

let deserializer = <u64 as IntoDeserializer>::into_deserializer(1);
let error = <&str>::deserialize(deserializer).unwrap_err();
assert_eq!(
error.to_string(),
"invalid type: integer `1`, expected a borrowed string",
);
}

#[test]
Expand All @@ -349,6 +367,13 @@ fn test_u128() {
&[Token::I64(-1)],
"invalid value: integer `-1`, expected u128",
);

let deserializer = <u128 as IntoDeserializer>::into_deserializer(1);
let error = <&str>::deserialize(deserializer).unwrap_err();
assert_eq!(
error.to_string(),
"invalid type: integer `1` as u128, expected a borrowed string",
);
}

#[test]
Expand Down

0 comments on commit c3ce2c9

Please sign in to comment.