1use crate::{DeserializeWith, SerializeWith};
4#[cfg(feature = "alloc")]
5use alloc::{borrow::Cow, boxed::Box, rc::Rc, string::String, vec::Vec};
6use core::{fmt, marker::PhantomData};
7use serde::{Deserializer, Serializer, de::Visitor};
8
9pub struct Bytes;
35
36impl Bytes {
37 pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
39 where
40 T: ?Sized,
41 S: Serializer,
42 Self: SerializeWith<T>,
43 {
44 Self::serialize_with(value, serializer)
45 }
46
47 pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
49 where
50 D: Deserializer<'de>,
51 Self: DeserializeWith<'de, T>,
52 {
53 Self::deserialize_with(deserializer)
54 }
55}
56
57impl<T> SerializeWith<T> for Bytes
58where
59 T: AsRef<[u8]> + ?Sized,
60{
61 fn serialize_with<S: Serializer>(value: &T, serializer: S) -> Result<S::Ok, S::Error> {
62 serializer.serialize_bytes(value.as_ref())
63 }
64}
65
66#[cfg(feature = "alloc")]
67impl<'de> DeserializeWith<'de, Vec<u8>> for Bytes {
68 fn deserialize_with<D>(deserializer: D) -> Result<Vec<u8>, D::Error>
69 where
70 D: Deserializer<'de>,
71 {
72 deserializer.deserialize_byte_buf(VecVisitor)
73 }
74}
75
76#[cfg(feature = "alloc")]
77impl<'de> DeserializeWith<'de, Box<[u8]>> for Bytes {
78 fn deserialize_with<D>(deserializer: D) -> Result<Box<[u8]>, D::Error>
79 where
80 D: Deserializer<'de>,
81 {
82 <Bytes as DeserializeWith<'de, Vec<u8>>>::deserialize_with(deserializer).map(Into::into)
83 }
84}
85
86#[cfg(feature = "alloc")]
87impl<'de> DeserializeWith<'de, Rc<[u8]>> for Bytes {
88 fn deserialize_with<D>(deserializer: D) -> Result<Rc<[u8]>, D::Error>
89 where
90 D: Deserializer<'de>,
91 {
92 <Bytes as DeserializeWith<'de, Vec<u8>>>::deserialize_with(deserializer).map(Into::into)
93 }
94}
95
96#[cfg(all(feature = "alloc", target_has_atomic = "ptr"))]
97impl<'de> DeserializeWith<'de, alloc::sync::Arc<[u8]>> for Bytes {
98 fn deserialize_with<D>(deserializer: D) -> Result<alloc::sync::Arc<[u8]>, D::Error>
99 where
100 D: Deserializer<'de>,
101 {
102 <Bytes as DeserializeWith<'de, Vec<u8>>>::deserialize_with(deserializer).map(Into::into)
103 }
104}
105
106impl<'de, const N: usize> DeserializeWith<'de, [u8; N]> for Bytes {
107 fn deserialize_with<D>(deserializer: D) -> Result<[u8; N], D::Error>
108 where
109 D: Deserializer<'de>,
110 {
111 deserializer.deserialize_bytes(ArrayVisitor::<N>)
112 }
113}
114
115impl<'de: 'a, 'a> DeserializeWith<'de, &'a [u8]> for Bytes {
116 fn deserialize_with<D>(deserializer: D) -> Result<&'a [u8], D::Error>
117 where
118 D: Deserializer<'de>,
119 {
120 deserializer.deserialize_bytes(SliceVisitor::default())
121 }
122}
123
124impl<'de: 'a, 'a, const N: usize> DeserializeWith<'de, &'a [u8; N]> for Bytes {
125 fn deserialize_with<D>(deserializer: D) -> Result<&'a [u8; N], D::Error>
126 where
127 D: Deserializer<'de>,
128 {
129 let bytes = deserializer.deserialize_bytes(SliceVisitor::default())?;
130 bytes
131 .try_into()
132 .map_err(|_| serde::de::Error::invalid_length(bytes.len(), &ArrayVisitor::<N>))
133 }
134}
135
136#[cfg(feature = "alloc")]
137impl<'de: 'a, 'a> DeserializeWith<'de, Cow<'a, [u8]>> for Bytes {
138 fn deserialize_with<D>(deserializer: D) -> Result<Cow<'a, [u8]>, D::Error>
139 where
140 D: Deserializer<'de>,
141 {
142 deserializer.deserialize_bytes(CowVisitor::default())
143 }
144}
145
146#[cfg(feature = "alloc")]
147struct VecVisitor;
148
149#[cfg(feature = "alloc")]
150impl<'de> Visitor<'de> for VecVisitor {
151 type Value = Vec<u8>;
152
153 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
154 f.write_str("bytes")
155 }
156
157 fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
158 where
159 E: serde::de::Error,
160 {
161 Ok(v)
162 }
163
164 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
165 where
166 E: serde::de::Error,
167 {
168 Ok(v.to_vec())
169 }
170
171 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
172 where
173 E: serde::de::Error,
174 {
175 Ok(v.into_bytes())
176 }
177
178 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
179 where
180 E: serde::de::Error,
181 {
182 Ok(v.as_bytes().to_vec())
183 }
184
185 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
186 where
187 A: serde::de::SeqAccess<'de>,
188 {
189 let mut bytes = Vec::with_capacity(seq.size_hint().unwrap_or(0).min(4096));
190 while let Some(b) = seq.next_element()? {
191 bytes.push(b);
192 }
193 Ok(bytes)
194 }
195}
196
197struct ArrayVisitor<const N: usize>;
198
199impl<'de, const N: usize> Visitor<'de> for ArrayVisitor<N> {
200 type Value = [u8; N];
201
202 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
203 write!(f, "a byte array of {N} bytes")
204 }
205
206 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
207 where
208 E: serde::de::Error,
209 {
210 v.try_into().map_err(|_| E::invalid_length(v.len(), &self))
211 }
212
213 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
214 where
215 E: serde::de::Error,
216 {
217 self.visit_bytes(v.as_bytes())
218 }
219
220 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
221 where
222 A: serde::de::SeqAccess<'de>,
223 {
224 let mut bytes = [0u8; N];
225 bytes.iter_mut().enumerate().try_for_each(|(i, out)| {
226 *out = seq
227 .next_element()?
228 .ok_or_else(|| serde::de::Error::invalid_length(i, &self))?;
229 Ok(())
230 })?;
231 Ok(bytes)
232 }
233}
234
235#[derive(Default)]
236struct SliceVisitor<'a>(PhantomData<&'a ()>);
237
238impl<'de: 'a, 'a> Visitor<'de> for SliceVisitor<'a> {
239 type Value = &'a [u8];
240
241 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
242 f.write_str("bytes")
243 }
244
245 fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
246 where
247 E: serde::de::Error,
248 {
249 Ok(v)
250 }
251
252 fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
253 where
254 E: serde::de::Error,
255 {
256 Ok(v.as_bytes())
257 }
258}
259
260#[cfg(feature = "alloc")]
261#[derive(Default)]
262struct CowVisitor<'a>(PhantomData<&'a ()>);
263
264#[cfg(feature = "alloc")]
265impl<'de: 'a, 'a> Visitor<'de> for CowVisitor<'a> {
266 type Value = Cow<'a, [u8]>;
267
268 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
269 f.write_str("bytes")
270 }
271
272 fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
273 where
274 E: serde::de::Error,
275 {
276 Ok(Cow::Borrowed(v))
277 }
278
279 fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
280 where
281 E: serde::de::Error,
282 {
283 Ok(Cow::Owned(v))
284 }
285
286 fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
287 where
288 E: serde::de::Error,
289 {
290 Ok(Cow::Owned(v.to_vec()))
291 }
292
293 fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
294 where
295 E: serde::de::Error,
296 {
297 Ok(Cow::Borrowed(v.as_bytes()))
298 }
299
300 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
301 where
302 E: serde::de::Error,
303 {
304 Ok(Cow::Owned(v.into_bytes()))
305 }
306
307 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
308 where
309 E: serde::de::Error,
310 {
311 Ok(Cow::Owned(v.as_bytes().to_vec()))
312 }
313
314 fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
315 where
316 A: serde::de::SeqAccess<'de>,
317 {
318 VecVisitor.visit_seq(seq).map(Into::into)
319 }
320}
321
322#[cfg(feature = "alloc")]
362pub struct ByteVec;
363
364#[cfg(feature = "alloc")]
365impl ByteVec {
366 pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
368 where
369 T: ?Sized,
370 S: Serializer,
371 Self: SerializeWith<T>,
372 {
373 Self::serialize_with(value, serializer)
374 }
375
376 pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
378 where
379 D: Deserializer<'de>,
380 Self: DeserializeWith<'de, T>,
381 {
382 Self::deserialize_with(deserializer)
383 }
384}
385
386#[cfg(feature = "alloc")]
387impl<T> SerializeWith<T> for ByteVec
388where
389 T: AsRef<[u8]> + ?Sized,
390{
391 fn serialize_with<S: Serializer>(value: &T, serializer: S) -> Result<S::Ok, S::Error> {
392 Bytes::serialize_with(value, serializer)
393 }
394}
395
396#[cfg(feature = "alloc")]
397impl<'de, T> DeserializeWith<'de, T> for ByteVec
398where
399 T: TryFrom<Vec<u8>>,
400 T::Error: core::fmt::Display,
401{
402 fn deserialize_with<D>(deserializer: D) -> Result<T, D::Error>
403 where
404 D: Deserializer<'de>,
405 {
406 let bytes: Vec<u8> = Bytes::deserialize_with(deserializer)?;
407 bytes.try_into().map_err(serde::de::Error::custom)
408 }
409}
410
411#[cfg(all(feature = "alloc", test))]
412mod tests {
413 use crate::test_utils::check_serialization;
414 use alloc::{borrow::Cow, boxed::Box, rc::Rc, vec, vec::Vec};
415 use core::fmt::Debug;
416 use serde::{Deserialize, Serialize};
417 use serde_json::json;
418
419 #[derive(Debug, Deserialize, PartialEq, Serialize)]
420 struct VecWrapper(#[serde(with = "crate::Bytes")] Vec<u8>);
421
422 #[test]
423 fn byte_vec_roundtrips() {
424 check_serialization(VecWrapper(vec![1, 2, 3]), json!([1, 2, 3]));
425 }
426
427 #[test]
428 fn empty_vec_roundtrips() {
429 check_serialization(VecWrapper(Vec::new()), json!([]));
430 }
431
432 #[derive(Debug, Deserialize, PartialEq, Serialize)]
433 struct SliceWrapper<'a>(#[serde(with = "crate::Bytes")] &'a [u8]);
434
435 #[test]
436 fn byte_slice_roundtrips() {
437 let original = SliceWrapper(b"foobar");
438 let serialized = bincode::serialize(&original).unwrap();
439 let deserialized = bincode::deserialize::<SliceWrapper<'_>>(&serialized).unwrap();
440 assert_eq!(deserialized, original);
441 }
442
443 #[derive(Debug, Deserialize, PartialEq, Serialize)]
444 struct BoxWrapper(#[serde(with = "crate::Bytes")] Box<[u8]>);
445
446 #[test]
447 fn boxed_bytes_roundtrip() {
448 check_serialization(BoxWrapper(vec![1, 2, 3].into()), json!([1, 2, 3]));
449 }
450
451 #[derive(Debug, Deserialize, PartialEq, Serialize)]
452 struct RcWrapper(#[serde(with = "crate::Bytes")] Rc<[u8]>);
453
454 #[test]
455 fn rced_bytes_roundtrip() {
456 check_serialization(RcWrapper(vec![1, 2, 3].into()), json!([1, 2, 3]));
457 }
458
459 #[cfg(target_has_atomic = "ptr")]
460 #[derive(Debug, Deserialize, PartialEq, Serialize)]
461 struct ArcWrapper(#[serde(with = "crate::Bytes")] alloc::sync::Arc<[u8]>);
462
463 #[cfg(target_has_atomic = "ptr")]
464 #[test]
465 fn arced_bytes_roundtrip() {
466 check_serialization(ArcWrapper(vec![1, 2, 3].into()), json!([1, 2, 3]));
467 }
468
469 #[derive(Debug, Deserialize, PartialEq, Serialize)]
470 struct ArrayWrapper<const N: usize>(#[serde(with = "crate::Bytes")] [u8; N]);
471
472 #[test]
473 fn byte_array_roundtrips() {
474 check_serialization(ArrayWrapper([1, 2, 3]), json!([1, 2, 3]));
475 }
476
477 #[test]
478 fn empty_byte_array_roundtrips() {
479 check_serialization(ArrayWrapper([]), json!([]));
480 }
481
482 #[derive(Debug, Deserialize, PartialEq, Serialize)]
483 struct RefArrayWrapper<'a, const N: usize>(
484 #[serde(borrow = "'a", with = "crate::Bytes")] &'a [u8; N],
485 );
486
487 #[test]
488 fn by_ref_byte_array_roundtrips() {
489 let original = RefArrayWrapper(b"foobar");
490 let serialized = bincode::serialize(&original).unwrap();
491 let deserialized = bincode::deserialize::<RefArrayWrapper<'_, 6>>(&serialized).unwrap();
492 assert_eq!(deserialized, original);
493 }
494
495 #[derive(Debug, Deserialize, PartialEq, Serialize)]
496 struct CowWrapper<'a>(#[serde(borrow = "'a", with = "crate::Bytes")] Cow<'a, [u8]>);
497
498 #[test]
499 fn cow_bytes_roundtrip() {
500 let original = CowWrapper(Cow::Borrowed(b"foobar"));
501 let serialized = bincode::serialize(&original).unwrap();
502 let deserialized = bincode::deserialize::<CowWrapper<'_>>(&serialized).unwrap();
503 assert_eq!(deserialized, original);
504 let CowWrapper(Cow::Borrowed(_)) = deserialized else {
505 panic!("Expected Cow::Borrowed");
506 };
507 }
508}