Merge pull request #1044 from Marwes/human_readable

Serialize to binary if the serde format is not human readable
This commit is contained in:
David Tolnay
2017-10-15 16:39:58 -07:00
committed by GitHub
12 changed files with 605 additions and 110 deletions
+118 -9
View File
@@ -28,7 +28,7 @@ extern crate fnv;
use self::fnv::FnvHasher;
extern crate serde_test;
use self::serde_test::{Token, assert_de_tokens, assert_de_tokens_error};
use self::serde_test::{Token, assert_de_tokens, assert_de_tokens_error, assert_de_tokens_readable};
#[macro_use]
mod macros;
@@ -110,15 +110,15 @@ enum EnumSkipAll {
//////////////////////////////////////////////////////////////////////////
macro_rules! declare_test {
($name:ident { $($value:expr => $tokens:expr,)+ }) => {
($name:ident $readable: ident { $($value:expr => $tokens:expr,)+ }) => {
#[test]
fn $name() {
$(
// Test ser/de roundtripping
assert_de_tokens(&$value, $tokens);
assert_de_tokens_readable(&$value, $tokens, $readable);
// Test that the tokens are ignorable
assert_de_tokens_ignore($tokens);
assert_de_tokens_ignore($tokens, true);
)+
}
}
@@ -127,7 +127,7 @@ macro_rules! declare_test {
macro_rules! declare_tests {
($($name:ident { $($value:expr => $tokens:expr,)+ })+) => {
$(
declare_test!($name { $($value => $tokens,)+ });
declare_test!($name true { $($value => $tokens,)+ });
)+
}
}
@@ -143,7 +143,16 @@ macro_rules! declare_error_tests {
}
}
fn assert_de_tokens_ignore(ignorable_tokens: &[Token]) {
macro_rules! declare_non_human_readable_tests {
($($name:ident { $($value:expr => $tokens:expr,)+ })+) => {
$(
declare_test!($name false { $($value => $tokens,)+ });
)+
}
}
fn assert_de_tokens_ignore(ignorable_tokens: &[Token], readable: bool) {
#[derive(PartialEq, Debug, Deserialize)]
struct IgnoreBase {
a: i32,
@@ -163,7 +172,7 @@ fn assert_de_tokens_ignore(ignorable_tokens: &[Token]) {
.chain(vec![Token::MapEnd].into_iter())
.collect();
let mut de = serde_test::Deserializer::new(&concated_tokens);
let mut de = serde_test::Deserializer::readable(&concated_tokens, readable);
let base = IgnoreBase::deserialize(&mut de).unwrap();
assert_eq!(base, IgnoreBase { a: 1 });
}
@@ -763,6 +772,70 @@ declare_tests! {
}
}
declare_non_human_readable_tests!{
test_non_human_readable_net_ipv4addr {
net::Ipv4Addr::from(*b"1234") => &seq![
Token::Tuple { len: 4 },
seq b"1234".iter().map(|&b| Token::U8(b)),
Token::TupleEnd
],
}
test_non_human_readable_net_ipv6addr {
net::Ipv6Addr::from(*b"1234567890123456") => &seq![
Token::Tuple { len: 4 },
seq b"1234567890123456".iter().map(|&b| Token::U8(b)),
Token::TupleEnd
],
}
test_non_human_readable_net_socketaddr {
net::SocketAddr::from((*b"1234567890123456", 1234)) => &seq![
Token::NewtypeVariant { name: "SocketAddr", variant: "V6" },
Token::Tuple { len: 2 },
Token::Tuple { len: 16 },
seq b"1234567890123456".iter().map(|&b| Token::U8(b)),
Token::TupleEnd,
Token::U16(1234),
Token::TupleEnd
],
net::SocketAddr::from((*b"1234", 1234)) => &seq![
Token::NewtypeVariant { name: "SocketAddr", variant: "V4" },
Token::Tuple { len: 2 },
Token::Tuple { len: 4 },
seq b"1234".iter().map(|&b| Token::U8(b)),
Token::TupleEnd,
Token::U16(1234),
Token::TupleEnd
],
net::SocketAddrV4::new(net::Ipv4Addr::from(*b"1234"), 1234) => &seq![
Token::Tuple { len: 2 },
Token::Tuple { len: 4 },
seq b"1234".iter().map(|&b| Token::U8(b)),
Token::TupleEnd,
Token::U16(1234),
Token::TupleEnd
],
net::SocketAddrV6::new(net::Ipv6Addr::from(*b"1234567890123456"), 1234, 0, 0) => &seq![
Token::Tuple { len: 2 },
Token::Tuple { len: 16 },
seq b"1234567890123456".iter().map(|&b| Token::U8(b)),
Token::TupleEnd,
Token::U16(1234),
Token::TupleEnd
],
}
}
#[cfg(feature = "unstable")]
declare_tests! {
test_rc_dst {
@@ -804,7 +877,7 @@ fn test_osstring() {
];
assert_de_tokens(&value, &tokens);
assert_de_tokens_ignore(&tokens);
assert_de_tokens_ignore(&tokens, true);
}
#[cfg(windows)]
@@ -824,7 +897,7 @@ fn test_osstring() {
];
assert_de_tokens(&value, &tokens);
assert_de_tokens_ignore(&tokens);
assert_de_tokens_ignore(&tokens, true);
}
#[cfg(feature = "unstable")]
@@ -1087,3 +1160,39 @@ declare_error_tests! {
"invalid type: sequence, expected unit struct UnitStruct",
}
}
#[derive(Debug, PartialEq)]
struct CompactBinary((u8, u8));
impl<'de> serde::Deserialize<'de> for CompactBinary {
fn deserialize<D>(deserializer: D) -> Result<CompactBinary, D::Error>
where
D: serde::Deserializer<'de>,
{
if deserializer.is_human_readable() {
<(u8, u8)>::deserialize(deserializer).map(CompactBinary)
} else {
<&[u8]>::deserialize(deserializer).map(|bytes| {
CompactBinary((bytes[0], bytes[1]))
})
}
}
}
#[test]
fn test_human_readable() {
assert_de_tokens(
&CompactBinary((1, 2)),
&[
Token::Tuple { len: 2},
Token::U8(1),
Token::U8(2),
Token::TupleEnd,
],
);
assert_de_tokens_readable(
&CompactBinary((1, 2)),
&[Token::BorrowedBytes(&[1, 2])],
false,
);
}