serde_human_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_human_bytes::Bytes` and `Vec<u8>` by wrapping it
10//! in `serde_human_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_derive::{Deserialize, Serialize};
18//! use serde::{Deserialize, Serialize};
19//!
20//! #[derive(Deserialize, Serialize)]
21//! struct Efficient<'a> {
22//! #[serde(with = "serde_human_bytes")]
23//! bytes: &'a [u8],
24//!
25//! #[serde(with = "serde_human_bytes")]
26//! byte_buf: Vec<u8>,
27//!
28//! #[serde(with = "serde_human_bytes")]
29//! byte_array: [u8; 314],
30//! }
31//! ```
32
33#![doc(html_root_url = "https://docs.rs/serde_human_bytes/0.11.15")]
34#![cfg_attr(not(feature = "std"), no_std)]
35#![deny(missing_docs)]
36#![allow(
37 clippy::into_iter_without_iter,
38 clippy::missing_errors_doc,
39 clippy::must_use_candidate,
40 clippy::needless_doctest_main,
41 clippy::needless_lifetimes,
42 clippy::ptr_as_ptr
43)]
44
45pub mod base64;
46mod bytearray;
47mod bytes;
48mod codec;
49mod de;
50mod ser;
51
52mod bytebuf;
53
54extern crate alloc;
55
56use serde::{Deserializer, Serializer};
57
58pub use crate::bytearray::ByteArray;
59pub use crate::bytes::Bytes;
60pub use crate::codec::{Base64, Codec, LowerHex, UpperHex};
61pub use crate::de::Deserialize;
62pub use crate::ser::Serialize;
63
64pub use crate::bytebuf::ByteBuf;
65
66/// Serde `serialize_with` function to serialize bytes efficiently.
67///
68/// This function can be used with either of the following Serde attributes:
69///
70/// - `#[serde(with = "serde_human_bytes")]`
71/// - `#[serde(serialize_with = "serde_human_bytes::serialize")]`
72///
73/// ```
74/// # use serde_derive::Serialize;
75/// use serde::Serialize;
76///
77/// #[derive(Serialize)]
78/// struct Efficient<'a> {
79/// #[serde(with = "serde_human_bytes")]
80/// bytes: &'a [u8],
81///
82/// #[serde(with = "serde_human_bytes")]
83/// byte_buf: Vec<u8>,
84///
85/// #[serde(with = "serde_human_bytes")]
86/// byte_array: [u8; 314],
87/// }
88/// ```
89pub fn serialize<T, S>(bytes: &T, serializer: S) -> Result<S::Ok, S::Error>
90where
91 T: ?Sized + Serialize,
92 S: Serializer,
93{
94 Serialize::serialize(bytes, serializer)
95}
96
97/// Serde `deserialize_with` function to deserialize bytes efficiently.
98///
99/// This function can be used with either of the following Serde attributes:
100///
101/// - `#[serde(with = "serde_human_bytes")]`
102/// - `#[serde(deserialize_with = "serde_human_bytes::deserialize")]`
103///
104/// ```
105/// # use serde_derive::Deserialize;
106/// use serde::Deserialize;
107///
108/// #[derive(Deserialize)]
109/// struct Packet {
110/// #[serde(with = "serde_human_bytes")]
111/// payload: Vec<u8>,
112///
113/// #[serde(with = "serde_human_bytes")]
114/// byte_array: [u8; 314],
115/// }
116/// ```
117pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
118where
119 T: Deserialize<'de>,
120 D: Deserializer<'de>,
121{
122 Deserialize::deserialize(deserializer)
123}
124
125/// UPPERCASE hex variant of the parent module.
126///
127/// Use as `#[serde(with = "serde_human_bytes::upper")]` when the wire format
128/// requires uppercase hex (e.g. Intel SGX/TDX PCCS payloads). Identical to
129/// the parent module for non-human-readable formats (still emits a compact
130/// byte sequence) and for deserialization (still case-insensitive).
131///
132/// ```
133/// # use serde_derive::{Deserialize, Serialize};
134/// use serde::{Deserialize, Serialize};
135///
136/// #[derive(Deserialize, Serialize)]
137/// struct Identity {
138/// #[serde(with = "serde_human_bytes::upper")]
139/// mrsigner: [u8; 32],
140/// }
141/// ```
142pub mod upper {
143 use serde::{Deserializer, Serializer};
144
145 /// Serde `serialize_with` function emitting UPPERCASE hex.
146 pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
147 where
148 T: ?Sized + crate::Serialize<crate::UpperHex>,
149 S: Serializer,
150 {
151 crate::Serialize::<crate::UpperHex>::serialize(value, serializer)
152 }
153
154 /// Serde `deserialize_with` function — case-insensitive hex.
155 pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
156 where
157 T: crate::Deserialize<'de, crate::UpperHex>,
158 D: Deserializer<'de>,
159 {
160 crate::Deserialize::<'de, crate::UpperHex>::deserialize(deserializer)
161 }
162}