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",
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],
}
Trait Implementations§
Source§impl<'de> DeserializeAs<'de, &'de [u8]> for Bytes
impl<'de> DeserializeAs<'de, &'de [u8]> for Bytes
Source§fn deserialize_as<D>(deserializer: D) -> Result<&'de [u8], D::Error>where
D: Deserializer<'de>,
fn deserialize_as<D>(deserializer: D) -> Result<&'de [u8], D::Error>where
D: Deserializer<'de>,
Source§impl<'de, const N: usize> DeserializeAs<'de, &'de [u8; N]> for Bytes
impl<'de, const N: usize> DeserializeAs<'de, &'de [u8; N]> for Bytes
Source§fn deserialize_as<D>(deserializer: D) -> Result<&'de [u8; N], D::Error>where
D: Deserializer<'de>,
fn deserialize_as<D>(deserializer: D) -> Result<&'de [u8; N], D::Error>where
D: Deserializer<'de>,
Source§impl<'de, const N: usize> DeserializeAs<'de, [u8; N]> for Bytes
impl<'de, const N: usize> DeserializeAs<'de, [u8; N]> for Bytes
Source§fn deserialize_as<D>(deserializer: D) -> Result<[u8; N], D::Error>where
D: Deserializer<'de>,
fn deserialize_as<D>(deserializer: D) -> Result<[u8; N], D::Error>where
D: Deserializer<'de>,
Source§impl<'de> DeserializeAs<'de, Box<[u8]>> for Bytes
impl<'de> DeserializeAs<'de, Box<[u8]>> for Bytes
Source§fn deserialize_as<D>(deserializer: D) -> Result<Box<[u8]>, D::Error>where
D: Deserializer<'de>,
fn deserialize_as<D>(deserializer: D) -> Result<Box<[u8]>, D::Error>where
D: Deserializer<'de>,
Source§impl<'de, const N: usize> DeserializeAs<'de, Box<[u8; N]>> for Bytes
impl<'de, const N: usize> DeserializeAs<'de, Box<[u8; N]>> for Bytes
Source§fn deserialize_as<D>(deserializer: D) -> Result<Box<[u8; N]>, D::Error>where
D: Deserializer<'de>,
fn deserialize_as<D>(deserializer: D) -> Result<Box<[u8; N]>, D::Error>where
D: Deserializer<'de>,
Source§impl<'de> DeserializeAs<'de, Cow<'de, [u8]>> for Bytes
impl<'de> DeserializeAs<'de, Cow<'de, [u8]>> for Bytes
Source§fn deserialize_as<D>(deserializer: D) -> Result<Cow<'de, [u8]>, D::Error>where
D: Deserializer<'de>,
fn deserialize_as<D>(deserializer: D) -> Result<Cow<'de, [u8]>, D::Error>where
D: Deserializer<'de>,
Source§impl<'de, const N: usize> DeserializeAs<'de, Cow<'de, [u8; N]>> for Bytes
impl<'de, const N: usize> DeserializeAs<'de, Cow<'de, [u8; N]>> for Bytes
Source§fn deserialize_as<D>(deserializer: D) -> Result<Cow<'de, [u8; N]>, D::Error>where
D: Deserializer<'de>,
fn deserialize_as<D>(deserializer: D) -> Result<Cow<'de, [u8; N]>, D::Error>where
D: Deserializer<'de>,
Source§impl<'de> DeserializeAs<'de, Vec<u8>> for Bytes
impl<'de> DeserializeAs<'de, Vec<u8>> for Bytes
Source§fn deserialize_as<D>(deserializer: D) -> Result<Vec<u8>, D::Error>where
D: Deserializer<'de>,
fn deserialize_as<D>(deserializer: D) -> Result<Vec<u8>, D::Error>where
D: Deserializer<'de>,
Source§impl<T> JsonSchemaAs<T> for Bytes
Available on crate feature schemars_0_8
only.
impl<T> JsonSchemaAs<T> for Bytes
schemars_0_8
only.Source§fn schema_name() -> String
fn schema_name() -> String
Source§fn schema_id() -> Cow<'static, str>
fn schema_id() -> Cow<'static, str>
Source§fn json_schema(gen: &mut SchemaGenerator) -> Schema
fn json_schema(gen: &mut SchemaGenerator) -> Schema
Source§fn is_referenceable() -> bool
fn is_referenceable() -> bool
$ref
keyword. Read more