Skip to main content

serde_bytes/
lib.rs

1//! Wrapper types to enable optimized handling of `&[u8]` and `Vec<u8>`.
2//!
3//! Without specialization, Rust forces Serde to treat `&[u8]` just like any
4//! other slice and `Vec<u8>` just like any other vector. In reality this
5//! particular slice and vector can often be serialized and deserialized in a
6//! more efficient, compact representation in many formats.
7//!
8//! When working with such a format, you can opt into specialized handling of
9//! `&[u8]` by wrapping it in `serde_bytes::Bytes` and `Vec<u8>` by wrapping it
10//! in `serde_bytes::ByteBuf`.
11//!
12//! Additionally this crate supports the Serde `with` attribute to enable
13//! efficient handling of `&[u8]` and `Vec<u8>` in structs without needing a
14//! wrapper type.
15//!
16//! ```
17//! use serde::{Deserialize, Serialize};
18//!
19//! #[derive(Deserialize, Serialize)]
20//! struct Efficient<'a> {
21//!     #[serde(with = "serde_bytes")]
22//!     bytes: &'a [u8],
23//!
24//!     #[serde(with = "serde_bytes")]
25//!     byte_buf: Vec<u8>,
26//!
27//!     #[serde(with = "serde_bytes")]
28//!     byte_array: [u8; 314],
29//! }
30//! ```
31
32#![cfg_attr(not(feature = "std"), no_std)]
33#![deny(missing_docs)]
34#![allow(
35    clippy::elidable_lifetime_names,
36    clippy::into_iter_without_iter,
37    clippy::missing_errors_doc,
38    clippy::must_use_candidate,
39    clippy::needless_doctest_main,
40    clippy::needless_lifetimes
41)]
42
43extern crate serde_core as serde;
44
45mod bytearray;
46mod bytes;
47mod de;
48mod ser;
49
50#[cfg(any(feature = "std", feature = "alloc"))]
51mod bytebuf;
52
53#[cfg(feature = "alloc")]
54extern crate alloc;
55
56use serde::{Deserializer, Serializer};
57
58#[cfg(any(feature = "std", feature = "alloc"))]
59pub use crate::bytebuf::ByteBuf;
60pub use crate::{bytearray::ByteArray, bytes::Bytes, de::Deserialize, ser::Serialize};
61
62/// Serde `serialize_with` function to serialize bytes efficiently.
63///
64/// This function can be used with either of the following Serde attributes:
65///
66/// - `#[serde(with = "serde_bytes")]`
67/// - `#[serde(serialize_with = "serde_bytes::serialize")]`
68///
69/// ```
70/// use serde::Serialize;
71///
72/// #[derive(Serialize)]
73/// struct Efficient<'a> {
74///     #[serde(with = "serde_bytes")]
75///     bytes: &'a [u8],
76///
77///     #[serde(with = "serde_bytes")]
78///     byte_buf: Vec<u8>,
79///
80///     #[serde(with = "serde_bytes")]
81///     byte_array: [u8; 314],
82/// }
83/// ```
84pub fn serialize<T, S>(bytes: &T, serializer: S) -> Result<S::Ok, S::Error>
85where
86    T: ?Sized + Serialize,
87    S: Serializer,
88{
89    Serialize::serialize(bytes, serializer)
90}
91
92/// Serde `deserialize_with` function to deserialize bytes efficiently.
93///
94/// This function can be used with either of the following Serde attributes:
95///
96/// - `#[serde(with = "serde_bytes")]`
97/// - `#[serde(deserialize_with = "serde_bytes::deserialize")]`
98///
99/// ```
100/// use serde::Deserialize;
101///
102/// #[derive(Deserialize)]
103/// struct Packet {
104///     #[serde(with = "serde_bytes")]
105///     payload: Vec<u8>,
106///
107///     #[serde(with = "serde_bytes")]
108///     byte_array: [u8; 314],
109/// }
110/// ```
111pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
112where
113    T: Deserialize<'de>,
114    D: Deserializer<'de>,
115{
116    Deserialize::deserialize(deserializer)
117}