Struct serde_with::Bytes
source · pub struct Bytes;
Expand description
Optimized handling of owned and borrowed byte representations.
Serialization of byte sequences like &[u8]
or Vec<u8>
is quite inefficient since each value will be serialized individually.
This converter type optimizes the serialization and deserialization.
This is a port of the serde_bytes
crate making it compatible with the serde_as
-annotation, which allows it to be used in more cases than provided by serde_bytes
.
The type provides de/serialization for these types:
[u8; N]
, not possible usingserde_bytes
&[u8; N]
, not possible usingserde_bytes
&[u8]
Box<[u8; N]>
, not possible usingserde_bytes
Box<[u8]>
Vec<u8>
Cow<'_, [u8]>
Cow<'_, [u8; N]>
, not possible usingserde_bytes
Examples
#[serde_as]
#[derive(Deserialize, Serialize)]
struct Test<'a> {
#[serde_as(as = "Bytes")]
array: [u8; 15],
#[serde_as(as = "Bytes")]
boxed: Box<[u8]>,
#[serde_as(as = "Bytes")]
#[serde(borrow)]
cow: Cow<'a, [u8]>,
#[serde_as(as = "Bytes")]
#[serde(borrow)]
cow_array: Cow<'a, [u8; 15]>,
#[serde_as(as = "Bytes")]
vec: Vec<u8>,
}
let value = Test {
array: b"0123456789ABCDE".clone(),
boxed: b"...".to_vec().into_boxed_slice(),
cow: Cow::Borrowed(b"FooBar"),
cow_array: Cow::Borrowed(&[42u8; 15]),
vec: vec![0x41, 0x61, 0x21],
};
let expected = r#"(
array: "MDEyMzQ1Njc4OUFCQ0RF",
boxed: "Li4u",
cow: "Rm9vQmFy",
cow_array: "KioqKioqKioqKioqKioq",
vec: "QWEh",
)"#;
assert_eq!(expected, ron::ser::to_string_pretty(&value, pretty_config).unwrap());
assert_eq!(value, ron::from_str(&expected).unwrap());
Fully borrowed types can also be used but you’ll need a Deserializer that supports Serde’s 0-copy deserialization:
#[serde_as]
#[derive(Deserialize, Serialize)]
struct TestBorrows<'a> {
#[serde_as(as = "Bytes")]
#[serde(borrow)]
array_buf: &'a [u8; 15],
#[serde_as(as = "Bytes")]
#[serde(borrow)]
buf: &'a [u8],
}
let value = TestBorrows {
array_buf: &[10u8; 15],
buf: &[20u8, 21u8, 22u8],
};
let expected = r#"(
array_buf: "CgoKCgoKCgoKCgoKCgoK",
buf: "FBUW",
)"#;
assert_eq!(expected, ron::ser::to_string_pretty(&value, pretty_config).unwrap());
// RON doesn't support borrowed deserialization of byte arrays
Alternative to BytesOrString
The Bytes
can replace BytesOrString
.
Bytes
is implemented for more types, which makes it better.
The serialization behavior of Bytes
differs from BytesOrString
, therefore only deserialize_as
should be used.
#[serde_as]
#[derive(Deserialize, serde::Serialize)]
struct Test {
#[serde_as(deserialize_as = "Bytes")]
from_bytes: Vec<u8>,
#[serde_as(deserialize_as = "Bytes")]
from_str: Vec<u8>,
}
// Different serialized values ...
let j = json!({
"from_bytes": [70,111,111,45,66,97,114],
"from_str": "Foo-Bar",
});
// can be deserialized ...
let test = Test {
from_bytes: b"Foo-Bar".to_vec(),
from_str: b"Foo-Bar".to_vec(),
};
assert_eq!(test, serde_json::from_value(j).unwrap());
// and serialization will always be a byte sequence
{
"from_bytes": [70,111,111,45,66,97,114],
"from_str": [70,111,111,45,66,97,114],
}