mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-24 16:58:00 +00:00
Merge pull request #1044 from Marwes/human_readable
Serialize to binary if the serde format is not human readable
This commit is contained in:
@@ -73,3 +73,29 @@ macro_rules! hashmap {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! seq_impl {
|
||||
(seq $first:expr,) => {
|
||||
seq_impl!(seq $first)
|
||||
};
|
||||
($first:expr,) => {
|
||||
seq_impl!($first)
|
||||
};
|
||||
(seq $first:expr) => {
|
||||
$first.into_iter()
|
||||
};
|
||||
($first:expr) => {
|
||||
Some($first).into_iter()
|
||||
};
|
||||
(seq $first:expr , $( $elem: tt)*) => {
|
||||
$first.into_iter().chain(seq!( $($elem)* ))
|
||||
};
|
||||
($first:expr , $($elem: tt)*) => {
|
||||
Some($first).into_iter().chain(seq!( $($elem)* ))
|
||||
}
|
||||
}
|
||||
macro_rules! seq {
|
||||
($($tt: tt)*) => {
|
||||
seq_impl!($($tt)*).collect::<Vec<_>>()
|
||||
};
|
||||
}
|
||||
|
||||
+118
-9
@@ -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,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
extern crate serde_test;
|
||||
use self::serde_test::{Token, assert_tokens_readable};
|
||||
|
||||
use std::net;
|
||||
|
||||
#[macro_use]
|
||||
#[allow(unused_macros)]
|
||||
mod macros;
|
||||
|
||||
#[test]
|
||||
fn ip_addr_roundtrip() {
|
||||
|
||||
assert_tokens_readable(
|
||||
&net::IpAddr::from(*b"1234"),
|
||||
&seq![
|
||||
Token::NewtypeVariant { name: "IpAddr", variant: "V4" },
|
||||
|
||||
Token::Tuple { len: 4 },
|
||||
seq b"1234".iter().map(|&b| Token::U8(b)),
|
||||
Token::TupleEnd,
|
||||
],
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn socked_addr_roundtrip() {
|
||||
|
||||
assert_tokens_readable(
|
||||
&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,
|
||||
],
|
||||
false,
|
||||
);
|
||||
}
|
||||
@@ -23,7 +23,8 @@ use std::str;
|
||||
extern crate serde;
|
||||
|
||||
extern crate serde_test;
|
||||
use self::serde_test::{Token, assert_ser_tokens, assert_ser_tokens_error};
|
||||
use self::serde_test::{Token, assert_ser_tokens, assert_ser_tokens_error,
|
||||
assert_ser_tokens_readable};
|
||||
|
||||
extern crate fnv;
|
||||
use self::fnv::FnvHasher;
|
||||
@@ -77,6 +78,19 @@ macro_rules! declare_tests {
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! declare_non_human_readable_tests {
|
||||
($($name:ident { $($value:expr => $tokens:expr,)+ })+) => {
|
||||
$(
|
||||
#[test]
|
||||
fn $name() {
|
||||
$(
|
||||
assert_ser_tokens_readable(&$value, $tokens, false);
|
||||
)+
|
||||
}
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
declare_tests! {
|
||||
test_unit {
|
||||
() => &[Token::Unit],
|
||||
@@ -397,6 +411,66 @@ 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: 16 },
|
||||
seq b"1234567890123456".iter().map(|&b| Token::U8(b)),
|
||||
Token::TupleEnd,
|
||||
],
|
||||
}
|
||||
test_non_human_readable_net_ipaddr {
|
||||
net::IpAddr::from(*b"1234") => &seq![
|
||||
Token::NewtypeVariant { name: "IpAddr", variant: "V4" },
|
||||
|
||||
Token::Tuple { len: 4 },
|
||||
seq b"1234".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::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,
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
// Serde's implementation is not unstable, but the constructors are.
|
||||
#[cfg(feature = "unstable")]
|
||||
declare_tests! {
|
||||
@@ -474,3 +548,26 @@ fn test_enum_skipped() {
|
||||
"the enum variant Enum::SkippedMap cannot be serialized",
|
||||
);
|
||||
}
|
||||
|
||||
struct CompactBinary(String);
|
||||
|
||||
impl serde::Serialize for CompactBinary {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer
|
||||
{
|
||||
if serializer.is_human_readable() {
|
||||
serializer.serialize_str(&self.0)
|
||||
} else {
|
||||
serializer.serialize_bytes(self.0.as_bytes())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_human_readable() {
|
||||
let value = CompactBinary("test".to_string());
|
||||
assert_ser_tokens(&value, &[Token::String("test")]);
|
||||
|
||||
assert_ser_tokens_readable(&value, &[Token::Bytes(b"test")], false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user