use serde_derive::{Deserialize, Serialize};
use serde_human_bytes::{ByteArray, ByteBuf, Bytes};
use serde_test::{
assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_tokens, Configure,
Readable, Token,
};
#[test]
fn test_bytes_readable() {
let empty = Bytes::new(&[]).readable();
assert_ser_tokens(&empty, &[Token::Str("")]);
assert_ser_tokens(&empty, &[Token::Str("")]);
let buf = vec![65, 66, 67];
let bytes = Bytes::new(&buf).readable();
assert_ser_tokens(&bytes, &[Token::Str("414243")]);
assert_ser_tokens(&bytes, &[Token::Str("414243")]);
}
#[test]
fn test_bytes() {
let empty = Bytes::new(&[]).compact();
assert_tokens(&empty, &[Token::BorrowedBytes(b"")]);
assert_ser_tokens(&empty, &[Token::Bytes(b"")]);
assert_ser_tokens(&empty, &[Token::ByteBuf(b"")]);
assert_de_tokens(&empty, &[Token::BorrowedStr("")]);
let buf = vec![65, 66, 67];
let bytes = Bytes::new(&buf).compact();
assert_tokens(&bytes, &[Token::BorrowedBytes(b"ABC")]);
assert_ser_tokens(&bytes, &[Token::Bytes(b"ABC")]);
assert_ser_tokens(&bytes, &[Token::ByteBuf(b"ABC")]);
assert_de_tokens(&bytes, &[Token::BorrowedStr("ABC")]);
}
#[test]
fn test_byte_buf_readable() {
let empty = ByteBuf::new().readable();
assert_tokens(&empty, &[Token::Str("")]);
assert_ser_tokens(&empty, &[Token::Str("")]);
assert_de_tokens(&empty, &[Token::Str("")]);
let buf = ByteBuf::from(vec![65, 66, 67]).readable();
assert_tokens(&buf, &[Token::Str("414243")]);
assert_de_tokens(&buf, &[Token::Str("414243")]);
}
#[test]
fn test_byte_buf() {
let empty = ByteBuf::new().compact();
assert_tokens(&empty, &[Token::BorrowedBytes(b"")]);
assert_tokens(&empty, &[Token::Bytes(b"")]);
assert_tokens(&empty, &[Token::ByteBuf(b"")]);
assert_de_tokens(&empty, &[Token::BorrowedStr("")]);
assert_de_tokens(&empty, &[Token::Str("")]);
assert_de_tokens(&empty, &[Token::String("")]);
assert_de_tokens(&empty, &[Token::Seq { len: None }, Token::SeqEnd]);
assert_de_tokens(&empty, &[Token::Seq { len: Some(0) }, Token::SeqEnd]);
let buf = ByteBuf::from(vec![65, 66, 67]).compact();
assert_tokens(&buf, &[Token::BorrowedBytes(b"ABC")]);
assert_tokens(&buf, &[Token::Bytes(b"ABC")]);
assert_tokens(&buf, &[Token::ByteBuf(b"ABC")]);
assert_de_tokens(&buf, &[Token::BorrowedStr("ABC")]);
assert_de_tokens(&buf, &[Token::Str("ABC")]);
assert_de_tokens(&buf, &[Token::String("ABC")]);
assert_de_tokens(
&buf,
&[
Token::Seq { len: None },
Token::U8(65),
Token::U8(66),
Token::U8(67),
Token::SeqEnd,
],
);
assert_de_tokens(
&buf,
&[
Token::Seq { len: Some(3) },
Token::U8(65),
Token::U8(66),
Token::U8(67),
Token::SeqEnd,
],
);
}
#[test]
fn test_bytearray_readable() {
let buf = [65, 66, 67];
let empty_readable = ByteArray::new([]).readable();
assert_tokens(&empty_readable, &[Token::Str("")]);
assert_ser_tokens(&empty_readable, &[Token::Str("")]);
assert_ser_tokens(&empty_readable, &[Token::Str("")]);
assert_de_tokens(&empty_readable, &[Token::Str("")]);
let bytes_readable = ByteArray::new(buf).readable();
assert_tokens(&bytes_readable, &[Token::Str("414243")]);
assert_ser_tokens(&bytes_readable, &[Token::Str("414243")]);
assert_ser_tokens(&bytes_readable, &[Token::Str("414243")]);
assert_de_tokens(&bytes_readable, &[Token::Str("414243")]);
}
#[test]
fn test_bytearray() {
let empty_compact = ByteArray::new([]).compact();
assert_tokens(&empty_compact, &[Token::BorrowedBytes(b"")]);
assert_ser_tokens(&empty_compact, &[Token::Bytes(b"")]);
assert_ser_tokens(&empty_compact, &[Token::ByteBuf(b"")]);
assert_de_tokens(&empty_compact, &[Token::BorrowedBytes(b"")]);
let buf = [65, 66, 67];
let bytes_compact = ByteArray::new(buf).compact();
assert_tokens(&bytes_compact, &[Token::BorrowedBytes(b"ABC")]);
assert_ser_tokens(&bytes_compact, &[Token::Bytes(b"ABC")]);
assert_ser_tokens(&bytes_compact, &[Token::ByteBuf(b"ABC")]);
assert_de_tokens(&bytes_compact, &[Token::BorrowedStr("ABC")]);
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Base64Example {
#[serde(with = "serde_human_bytes::base64")]
data: Vec<u8>,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Base64ArrayExample {
#[serde(with = "serde_human_bytes::base64")]
data: [u8; 3],
}
#[test]
fn test_base64_vec_readable() {
let example = Base64Example {
data: vec![65, 66, 67],
}
.readable();
assert_tokens(
&example,
&[
Token::Struct {
name: "Base64Example",
len: 1,
},
Token::Str("data"),
Token::Str("QUJD"),
Token::StructEnd,
],
);
}
#[test]
fn test_base64_vec_compact() {
let example = Base64Example {
data: vec![65, 66, 67],
}
.compact();
assert_tokens(
&example,
&[
Token::Struct {
name: "Base64Example",
len: 1,
},
Token::Str("data"),
Token::Bytes(b"ABC"),
Token::StructEnd,
],
);
}
#[test]
fn test_base64_array_readable() {
let example = Base64ArrayExample { data: [65, 66, 67] }.readable();
assert_tokens(
&example,
&[
Token::Struct {
name: "Base64ArrayExample",
len: 1,
},
Token::Str("data"),
Token::Str("QUJD"),
Token::StructEnd,
],
);
}
#[test]
fn test_base64_array_compact() {
let example = Base64ArrayExample { data: [65, 66, 67] }.compact();
assert_tokens(
&example,
&[
Token::Struct {
name: "Base64ArrayExample",
len: 1,
},
Token::Str("data"),
Token::Bytes(b"ABC"),
Token::StructEnd,
],
);
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct UpperArray {
#[serde(with = "serde_human_bytes::upper")]
data: [u8; 3],
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct UpperVec {
#[serde(with = "serde_human_bytes::upper")]
data: Vec<u8>,
}
#[test]
fn test_upper_array_readable_is_uppercase() {
let example = UpperArray {
data: [0xab, 0xcd, 0xef],
}
.readable();
assert_tokens(
&example,
&[
Token::Struct {
name: "UpperArray",
len: 1,
},
Token::Str("data"),
Token::Str("ABCDEF"),
Token::StructEnd,
],
);
}
#[test]
fn test_upper_vec_readable_is_uppercase() {
let example = UpperVec {
data: vec![0x8c, 0x4f, 0x57],
}
.readable();
assert_tokens(
&example,
&[
Token::Struct {
name: "UpperVec",
len: 1,
},
Token::Str("data"),
Token::Str("8C4F57"),
Token::StructEnd,
],
);
}
#[test]
fn test_upper_decode_accepts_mixed_case() {
for hex in ["abcdef", "ABCDEF", "AbCdEf"] {
let expected = UpperArray {
data: [0xab, 0xcd, 0xef],
}
.readable();
assert_de_tokens(
&expected,
&[
Token::Struct {
name: "UpperArray",
len: 1,
},
Token::Str("data"),
Token::Str(hex),
Token::StructEnd,
],
);
}
}
#[test]
fn test_upper_compact_emits_binary() {
let example = UpperArray {
data: [0x41, 0x42, 0x43],
}
.compact();
assert_ser_tokens(
&example,
&[
Token::Struct {
name: "UpperArray",
len: 1,
},
Token::Str("data"),
Token::Bytes(b"ABC"),
Token::StructEnd,
],
);
}
#[test]
fn test_upper_bincode_roundtrip() {
let original = UpperArray {
data: [0x8c, 0x4f, 0x57],
};
let bytes = bincode::serialize(&original).unwrap();
assert!(bytes.windows(3).any(|w| w == [0x8c, 0x4f, 0x57]));
let decoded: UpperArray = bincode::deserialize(&bytes).unwrap();
assert_eq!(original, decoded);
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct LowerArray {
#[serde(with = "serde_human_bytes")]
data: [u8; 3],
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct LowerVec {
#[serde(with = "serde_human_bytes")]
data: Vec<u8>,
}
#[test]
fn test_lower_array_readable() {
let example = LowerArray {
data: [0xab, 0xcd, 0xef],
}
.readable();
assert_tokens(
&example,
&[
Token::Struct {
name: "LowerArray",
len: 1,
},
Token::Str("data"),
Token::Str("abcdef"),
Token::StructEnd,
],
);
}
#[test]
fn test_lower_vec_readable() {
let example = LowerVec {
data: vec![0x8c, 0x4f, 0x57],
}
.readable();
assert_tokens(
&example,
&[
Token::Struct {
name: "LowerVec",
len: 1,
},
Token::Str("data"),
Token::Str("8c4f57"),
Token::StructEnd,
],
);
}
#[test]
fn test_lower_decode_accepts_uppercase() {
let expected = LowerArray {
data: [0xab, 0xcd, 0xef],
}
.readable();
assert_de_tokens(
&expected,
&[
Token::Struct {
name: "LowerArray",
len: 1,
},
Token::Str("data"),
Token::Str("ABCDEF"),
Token::StructEnd,
],
);
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct OptLower {
#[serde(with = "serde_human_bytes")]
data: Option<Vec<u8>>,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct OptUpper {
#[serde(with = "serde_human_bytes::upper")]
data: Option<Vec<u8>>,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct OptBase64 {
#[serde(with = "serde_human_bytes::base64")]
data: Option<Vec<u8>>,
}
#[test]
fn test_option_lower_some() {
let v = OptLower {
data: Some(vec![0xab, 0xcd, 0xef]),
}
.readable();
assert_tokens(
&v,
&[
Token::Struct {
name: "OptLower",
len: 1,
},
Token::Str("data"),
Token::Some,
Token::Str("abcdef"),
Token::StructEnd,
],
);
}
#[test]
fn test_option_upper_some() {
let v = OptUpper {
data: Some(vec![0xab, 0xcd, 0xef]),
}
.readable();
assert_tokens(
&v,
&[
Token::Struct {
name: "OptUpper",
len: 1,
},
Token::Str("data"),
Token::Some,
Token::Str("ABCDEF"),
Token::StructEnd,
],
);
}
#[test]
fn test_option_base64_some() {
let v = OptBase64 {
data: Some(vec![0x41, 0x42, 0x43]),
}
.readable();
assert_tokens(
&v,
&[
Token::Struct {
name: "OptBase64",
len: 1,
},
Token::Str("data"),
Token::Some,
Token::Str("QUJD"),
Token::StructEnd,
],
);
}
#[test]
fn test_option_none_all_codecs() {
assert_tokens(
&OptLower { data: None }.readable(),
&[
Token::Struct {
name: "OptLower",
len: 1,
},
Token::Str("data"),
Token::None,
Token::StructEnd,
],
);
assert_tokens(
&OptUpper { data: None }.readable(),
&[
Token::Struct {
name: "OptUpper",
len: 1,
},
Token::Str("data"),
Token::None,
Token::StructEnd,
],
);
assert_tokens(
&OptBase64 { data: None }.readable(),
&[
Token::Struct {
name: "OptBase64",
len: 1,
},
Token::Str("data"),
Token::None,
Token::StructEnd,
],
);
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct BoxLower {
#[serde(with = "serde_human_bytes")]
data: Box<[u8]>,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct BoxUpper {
#[serde(with = "serde_human_bytes::upper")]
data: Box<[u8]>,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct BoxBase64 {
#[serde(with = "serde_human_bytes::base64")]
data: Box<[u8]>,
}
#[test]
fn test_box_slice_lower_roundtrip() {
let v = BoxLower {
data: vec![0xab, 0xcd, 0xef].into_boxed_slice(),
}
.readable();
assert_tokens(
&v,
&[
Token::Struct {
name: "BoxLower",
len: 1,
},
Token::Str("data"),
Token::Str("abcdef"),
Token::StructEnd,
],
);
}
#[test]
fn test_box_slice_upper_roundtrip() {
let v = BoxUpper {
data: vec![0xab, 0xcd, 0xef].into_boxed_slice(),
}
.readable();
assert_tokens(
&v,
&[
Token::Struct {
name: "BoxUpper",
len: 1,
},
Token::Str("data"),
Token::Str("ABCDEF"),
Token::StructEnd,
],
);
}
#[test]
fn test_box_slice_base64_roundtrip() {
let v = BoxBase64 {
data: vec![0x41, 0x42, 0x43].into_boxed_slice(),
}
.readable();
assert_tokens(
&v,
&[
Token::Struct {
name: "BoxBase64",
len: 1,
},
Token::Str("data"),
Token::Str("QUJD"),
Token::StructEnd,
],
);
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct ByteBufUpper {
#[serde(with = "serde_human_bytes::upper")]
data: ByteBuf,
}
#[test]
fn test_bytebuf_upper_roundtrip() {
let v = ByteBufUpper {
data: ByteBuf::from(vec![0xab, 0xcd, 0xef]),
}
.readable();
assert_tokens(
&v,
&[
Token::Struct {
name: "ByteBufUpper",
len: 1,
},
Token::Str("data"),
Token::Str("ABCDEF"),
Token::StructEnd,
],
);
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct ByteArrayUpper {
#[serde(with = "serde_human_bytes::upper")]
data: ByteArray<3>,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct CowLower<'a> {
#[serde(with = "serde_human_bytes", borrow)]
data: std::borrow::Cow<'a, [u8]>,
}
#[test]
fn test_cow_lower_readable_roundtrip() {
let owned = CowLower {
data: std::borrow::Cow::Owned(vec![0xab, 0xcd, 0xef]),
}
.readable();
assert_tokens(
&owned,
&[
Token::Struct {
name: "CowLower",
len: 1,
},
Token::Str("data"),
Token::Str("abcdef"),
Token::StructEnd,
],
);
}
#[test]
fn test_cow_lower_compact_borrowed() {
let original = CowLower {
data: std::borrow::Cow::Borrowed(b"\xab\xcd\xef"),
}
.compact();
assert_ser_tokens(
&original,
&[
Token::Struct {
name: "CowLower",
len: 1,
},
Token::Str("data"),
Token::Bytes(b"\xab\xcd\xef"),
Token::StructEnd,
],
);
}
#[test]
fn test_bytearray_upper_roundtrip() {
let v = ByteArrayUpper {
data: ByteArray::new([0xab, 0xcd, 0xef]),
}
.readable();
assert_tokens(
&v,
&[
Token::Struct {
name: "ByteArrayUpper",
len: 1,
},
Token::Str("data"),
Token::Str("ABCDEF"),
Token::StructEnd,
],
);
}
#[test]
fn test_invalid_hex_rejected() {
assert_de_tokens_error::<Readable<LowerArray>>(
&[
Token::Struct {
name: "LowerArray",
len: 1,
},
Token::Str("data"),
Token::Str("zzcdef"),
Token::StructEnd,
],
"Invalid character 'z' at position 0",
);
}
#[test]
fn test_invalid_base64_rejected() {
assert_de_tokens_error::<Readable<Base64Example>>(
&[
Token::Struct {
name: "Base64Example",
len: 1,
},
Token::Str("data"),
Token::Str("not_valid_base64!!"),
Token::StructEnd,
],
"Invalid byte 95, offset 3.",
);
}
#[test]
fn test_array_length_mismatch_lower() {
assert_de_tokens_error::<Readable<LowerArray>>(
&[
Token::Struct {
name: "LowerArray",
len: 1,
},
Token::Str("data"),
Token::Str("abcd"), Token::StructEnd,
],
"invalid array length",
);
}
#[test]
fn test_array_length_mismatch_upper() {
assert_de_tokens_error::<Readable<UpperArray>>(
&[
Token::Struct {
name: "UpperArray",
len: 1,
},
Token::Str("data"),
Token::Str("ABCD"), Token::StructEnd,
],
"invalid array length",
);
}
#[test]
fn test_array_length_mismatch_base64() {
assert_de_tokens_error::<Readable<Base64ArrayExample>>(
&[
Token::Struct {
name: "Base64ArrayExample",
len: 1,
},
Token::Str("data"),
Token::Str("QUI="), Token::StructEnd,
],
"invalid array length",
);
}