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: b"0123456789ABCDE",
boxed: b"...",
cow: b"FooBar",
cow_array: b"***************",
vec: b"Aa!",
)"#;
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: b"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",
buf: b"\x14\x15\x16",
)"#;
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 SerializeAs<&[u8]> for Bytes
impl SerializeAs<&[u8]> for Bytes
Source§fn serialize_as<S>(bytes: &&[u8], serializer: S) -> Result<S::Ok, S::Error>where
S: Serializer,
fn serialize_as<S>(bytes: &&[u8], serializer: S) -> Result<S::Ok, S::Error>where
S: Serializer,
Source§impl<const N: usize> SerializeAs<&[u8; N]> for Bytes
impl<const N: usize> SerializeAs<&[u8; N]> for Bytes
Source§fn serialize_as<S>(bytes: &&[u8; N], serializer: S) -> Result<S::Ok, S::Error>where
S: Serializer,
fn serialize_as<S>(bytes: &&[u8; N], serializer: S) -> Result<S::Ok, S::Error>where
S: Serializer,
Source§impl<const N: usize> SerializeAs<[u8; N]> for Bytes
impl<const N: usize> SerializeAs<[u8; N]> for Bytes
Source§fn serialize_as<S>(bytes: &[u8; N], serializer: S) -> Result<S::Ok, S::Error>where
S: Serializer,
fn serialize_as<S>(bytes: &[u8; N], serializer: S) -> Result<S::Ok, S::Error>where
S: Serializer,
Source§impl SerializeAs<Box<[u8]>> for Bytes
impl SerializeAs<Box<[u8]>> for Bytes
Source§fn serialize_as<S>(bytes: &Box<[u8]>, serializer: S) -> Result<S::Ok, S::Error>where
S: Serializer,
fn serialize_as<S>(bytes: &Box<[u8]>, serializer: S) -> Result<S::Ok, S::Error>where
S: Serializer,
Source§impl<const N: usize> SerializeAs<Box<[u8; N]>> for Bytes
impl<const N: usize> SerializeAs<Box<[u8; N]>> for Bytes
Source§fn serialize_as<S>(
bytes: &Box<[u8; N]>,
serializer: S,
) -> Result<S::Ok, S::Error>where
S: Serializer,
fn serialize_as<S>(
bytes: &Box<[u8; N]>,
serializer: S,
) -> Result<S::Ok, S::Error>where
S: Serializer,
Source§impl<'a> SerializeAs<Cow<'a, [u8]>> for Bytes
impl<'a> SerializeAs<Cow<'a, [u8]>> for Bytes
Source§fn serialize_as<S>(
bytes: &Cow<'a, [u8]>,
serializer: S,
) -> Result<S::Ok, S::Error>where
S: Serializer,
fn serialize_as<S>(
bytes: &Cow<'a, [u8]>,
serializer: S,
) -> Result<S::Ok, S::Error>where
S: Serializer,
Source§impl<'a, const N: usize> SerializeAs<Cow<'a, [u8; N]>> for Bytes
impl<'a, const N: usize> SerializeAs<Cow<'a, [u8; N]>> for Bytes
Source§fn serialize_as<S>(
bytes: &Cow<'a, [u8; N]>,
serializer: S,
) -> Result<S::Ok, S::Error>where
S: Serializer,
fn serialize_as<S>(
bytes: &Cow<'a, [u8; N]>,
serializer: S,
) -> Result<S::Ok, S::Error>where
S: Serializer,
Source§impl SerializeAs<Vec<u8>> for Bytes
impl SerializeAs<Vec<u8>> for Bytes
Source§fn serialize_as<S>(bytes: &Vec<u8>, serializer: S) -> Result<S::Ok, S::Error>where
S: Serializer,
fn serialize_as<S>(bytes: &Vec<u8>, serializer: S) -> Result<S::Ok, S::Error>where
S: Serializer,
Auto Trait Implementations§
impl Freeze for Bytes
impl RefUnwindSafe for Bytes
impl Send for Bytes
impl Sync for Bytes
impl Unpin for Bytes
impl UnwindSafe for Bytes
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Layout§
Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...)
attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.
Size: 0 bytes