bincode_next/features/
impl_alloc.rs

1#![allow(unsafe_code)]
2use crate::{
3    de::{read::Reader, BorrowDecoder, Decode, Decoder},
4    enc::{
5        self,
6        write::{SizeWriter, Writer},
7        Encode, Encoder,
8    },
9    error::{DecodeError, EncodeError},
10    impl_borrow_decode, BorrowDecode, Config,
11};
12use alloc::{
13    borrow::{Cow, ToOwned},
14    boxed::Box,
15    collections::{BTreeMap, BTreeSet, BinaryHeap, VecDeque},
16    rc::Rc,
17    string::String,
18    vec::Vec,
19};
20
21#[cfg(target_has_atomic = "ptr")]
22use alloc::sync::Arc;
23
24/// A writer that writes into a `Vec<u8>`.
25#[derive(Default)]
26pub struct VecWriter {
27    inner: Vec<u8>,
28}
29
30impl VecWriter {
31    /// Create a new vec writer with the given capacity
32    #[must_use]
33    pub fn with_capacity(cap: usize) -> Self {
34        Self {
35            inner: Vec::with_capacity(cap),
36        }
37    }
38    // May not be used in all feature combinations
39    #[allow(dead_code)]
40    pub(crate) fn collect(self) -> Vec<u8> {
41        self.inner
42    }
43}
44
45impl enc::write::Writer for VecWriter {
46    #[inline]
47    fn write(&mut self, bytes: &[u8]) -> Result<(), EncodeError> {
48        self.inner.extend_from_slice(bytes);
49        Ok(())
50    }
51}
52
53/// Encode the given value into a `Vec<u8>` with the given `Config`. See the [config] module for more information.
54///
55/// [config]: config/index.html
56/// # Errors
57///
58/// Returns an `EncodeError` if the value cannot be encoded.
59#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
60pub fn encode_to_vec<E: enc::Encode, C: Config>(val: E, config: C) -> Result<Vec<u8>, EncodeError> {
61    let size = {
62        let mut size_writer = enc::EncoderImpl::<_, C>::new(SizeWriter::default(), config);
63        val.encode(&mut size_writer)?;
64        size_writer.into_writer().bytes_written
65    };
66    let writer = VecWriter::with_capacity(size);
67    let mut encoder = enc::EncoderImpl::<_, C>::new(writer, config);
68    val.encode(&mut encoder)?;
69    Ok(encoder.into_writer().inner)
70}
71
72impl<Context, T> Decode<Context> for BinaryHeap<T>
73where
74    T: Decode<Context> + Ord,
75{
76    fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
77        Ok(Vec::<T>::decode(decoder)?.into())
78    }
79}
80impl<'de, T, Context> BorrowDecode<'de, Context> for BinaryHeap<T>
81where
82    T: BorrowDecode<'de, Context> + Ord,
83{
84    fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
85        decoder: &mut D,
86    ) -> Result<Self, DecodeError> {
87        Ok(Vec::<T>::borrow_decode(decoder)?.into())
88    }
89}
90
91impl<T> Encode for BinaryHeap<T>
92where
93    T: Encode + Ord,
94{
95    fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
96        // BLOCKEDTODO(https://github.com/rust-lang/rust/issues/83659): we can u8 optimize this with `.as_slice()`
97        crate::enc::encode_slice_len(encoder, self.len())?;
98        for val in self {
99            val.encode(encoder)?;
100        }
101        Ok(())
102    }
103}
104
105impl<Context, K, V> Decode<Context> for BTreeMap<K, V>
106where
107    K: Decode<Context> + Ord,
108    V: Decode<Context>,
109{
110    fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
111        let len = crate::de::decode_slice_len(decoder)?;
112        decoder.claim_container_read::<(K, V)>(len)?;
113
114        let mut map = Self::new();
115        for _ in 0..len {
116            // See the documentation on `unclaim_bytes_read` as to why we're doing this here
117            decoder.unclaim_bytes_read(core::mem::size_of::<(K, V)>());
118
119            let key = K::decode(decoder)?;
120            let value = V::decode(decoder)?;
121            map.insert(key, value);
122        }
123        Ok(map)
124    }
125}
126impl<'de, K, V, Context> BorrowDecode<'de, Context> for BTreeMap<K, V>
127where
128    K: BorrowDecode<'de, Context> + Ord,
129    V: BorrowDecode<'de, Context>,
130{
131    fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
132        decoder: &mut D,
133    ) -> Result<Self, DecodeError> {
134        let len = crate::de::decode_slice_len(decoder)?;
135        decoder.claim_container_read::<(K, V)>(len)?;
136
137        let mut map = Self::new();
138        for _ in 0..len {
139            // See the documentation on `unclaim_bytes_read` as to why we're doing this here
140            decoder.unclaim_bytes_read(core::mem::size_of::<(K, V)>());
141
142            let key = K::borrow_decode(decoder)?;
143            let value = V::borrow_decode(decoder)?;
144            map.insert(key, value);
145        }
146        Ok(map)
147    }
148}
149
150impl<K, V> Encode for BTreeMap<K, V>
151where
152    K: Encode + Ord,
153    V: Encode,
154{
155    fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
156        crate::enc::encode_slice_len(encoder, self.len())?;
157        for (key, val) in self {
158            key.encode(encoder)?;
159            val.encode(encoder)?;
160        }
161        Ok(())
162    }
163}
164
165impl<Context, T> Decode<Context> for BTreeSet<T>
166where
167    T: Decode<Context> + Ord,
168{
169    fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
170        let len = crate::de::decode_slice_len(decoder)?;
171        decoder.claim_container_read::<T>(len)?;
172
173        let mut map = Self::new();
174        for _ in 0..len {
175            // See the documentation on `unclaim_bytes_read` as to why we're doing this here
176            decoder.unclaim_bytes_read(core::mem::size_of::<T>());
177
178            let key = T::decode(decoder)?;
179            map.insert(key);
180        }
181        Ok(map)
182    }
183}
184impl<'de, T, Context> BorrowDecode<'de, Context> for BTreeSet<T>
185where
186    T: BorrowDecode<'de, Context> + Ord,
187{
188    fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
189        decoder: &mut D,
190    ) -> Result<Self, DecodeError> {
191        let len = crate::de::decode_slice_len(decoder)?;
192        decoder.claim_container_read::<T>(len)?;
193
194        let mut map = Self::new();
195        for _ in 0..len {
196            // See the documentation on `unclaim_bytes_read` as to why we're doing this here
197            decoder.unclaim_bytes_read(core::mem::size_of::<T>());
198
199            let key = T::borrow_decode(decoder)?;
200            map.insert(key);
201        }
202        Ok(map)
203    }
204}
205
206impl<T> Encode for BTreeSet<T>
207where
208    T: Encode + Ord,
209{
210    fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
211        crate::enc::encode_slice_len(encoder, self.len())?;
212        for item in self {
213            item.encode(encoder)?;
214        }
215        Ok(())
216    }
217}
218
219impl<Context, T> Decode<Context> for VecDeque<T>
220where
221    T: Decode<Context>,
222{
223    fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
224        Ok(Vec::<T>::decode(decoder)?.into())
225    }
226}
227impl<'de, T, Context> BorrowDecode<'de, Context> for VecDeque<T>
228where
229    T: BorrowDecode<'de, Context>,
230{
231    fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
232        decoder: &mut D,
233    ) -> Result<Self, DecodeError> {
234        Ok(Vec::<T>::borrow_decode(decoder)?.into())
235    }
236}
237
238impl<T> Encode for VecDeque<T>
239where
240    T: Encode,
241{
242    fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
243        crate::enc::encode_slice_len(encoder, self.len())?;
244        if unty::type_equal::<T, u8>() {
245            let slices: (&[T], &[T]) = self.as_slices();
246            // Safety: T is u8 so turning this into `&[u8]` is okay
247            let slices: (&[u8], &[u8]) = unsafe {
248                (
249                    core::slice::from_raw_parts(slices.0.as_ptr().cast(), slices.0.len()),
250                    core::slice::from_raw_parts(slices.1.as_ptr().cast(), slices.1.len()),
251                )
252            };
253
254            encoder.writer().write(slices.0)?;
255            encoder.writer().write(slices.1)?;
256        } else {
257            for item in self {
258                item.encode(encoder)?;
259            }
260        }
261        Ok(())
262    }
263}
264
265impl<Context, T> Decode<Context> for Vec<T>
266where
267    T: Decode<Context>,
268{
269    fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
270        let len = crate::de::decode_slice_len(decoder)?;
271
272        decoder.claim_container_read::<T>(len)?;
273        if unty::type_equal::<T, u8>() {
274            // optimize for reading u8 vecs
275            let mut vec = alloc::vec![0u8; len];
276            decoder.reader().read(&mut vec)?;
277            // Safety: Vec<T> is Vec<u8>
278            Ok(unsafe { core::mem::transmute::<Vec<u8>, Self>(vec) })
279        } else {
280            let mut vec = Self::with_capacity(len);
281            for _ in 0..len {
282                // See the documentation on `unclaim_bytes_read` as to why we're doing this here
283                decoder.unclaim_bytes_read(core::mem::size_of::<T>());
284
285                vec.push(T::decode(decoder)?);
286            }
287            Ok(vec)
288        }
289    }
290}
291
292impl<'de, T, Context> BorrowDecode<'de, Context> for Vec<T>
293where
294    T: BorrowDecode<'de, Context>,
295{
296    fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
297        decoder: &mut D,
298    ) -> Result<Self, DecodeError> {
299        let len = crate::de::decode_slice_len(decoder)?;
300
301        decoder.claim_container_read::<T>(len)?;
302        if unty::type_equal::<T, u8>() {
303            // optimize for reading u8 vecs
304            let mut vec = alloc::vec![0u8; len];
305            decoder.reader().read(&mut vec)?;
306            // Safety: Vec<T> is Vec<u8>
307            Ok(unsafe { core::mem::transmute::<Vec<u8>, Self>(vec) })
308        } else {
309            let mut vec = Self::with_capacity(len);
310            for _ in 0..len {
311                // See the documentation on `unclaim_bytes_read` as to why we're doing this here
312                decoder.unclaim_bytes_read(core::mem::size_of::<T>());
313
314                vec.push(T::borrow_decode(decoder)?);
315            }
316            Ok(vec)
317        }
318    }
319}
320
321impl<T> Encode for Vec<T>
322where
323    T: Encode,
324{
325    fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
326        crate::enc::encode_slice_len(encoder, self.len())?;
327        if unty::type_equal::<T, u8>() {
328            // Safety: T == u8
329            let slice: &[u8] =
330                unsafe { &*(core::ptr::from_ref::<[T]>(self.as_slice()) as *const [u8]) };
331            encoder.writer().write(slice)?;
332        } else {
333            for item in self {
334                item.encode(encoder)?;
335            }
336        }
337        Ok(())
338    }
339}
340
341impl<Context> Decode<Context> for String {
342    fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
343        let bytes = Vec::<u8>::decode(decoder)?;
344        Self::from_utf8(bytes).map_err(|e| DecodeError::Utf8 {
345            inner: e.utf8_error(),
346        })
347    }
348}
349impl_borrow_decode!(String);
350
351impl<Context> Decode<Context> for Box<str> {
352    fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
353        String::decode(decoder).map(String::into_boxed_str)
354    }
355}
356impl_borrow_decode!(Box<str>);
357
358impl Encode for String {
359    fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
360        self.as_bytes().encode(encoder)
361    }
362}
363
364impl<Context, T> Decode<Context> for Box<T>
365where
366    T: Decode<Context>,
367{
368    fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
369        let t = T::decode(decoder)?;
370        Ok(Self::new(t))
371    }
372}
373impl<'de, T, Context> BorrowDecode<'de, Context> for Box<T>
374where
375    T: BorrowDecode<'de, Context>,
376{
377    fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
378        decoder: &mut D,
379    ) -> Result<Self, DecodeError> {
380        let t = T::borrow_decode(decoder)?;
381        Ok(Self::new(t))
382    }
383}
384
385impl<T> Encode for Box<T>
386where
387    T: Encode + ?Sized,
388{
389    fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
390        T::encode(self, encoder)
391    }
392}
393
394impl<Context, T> Decode<Context> for Box<[T]>
395where
396    T: Decode<Context> + 'static,
397{
398    fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
399        let vec = Vec::decode(decoder)?;
400        Ok(vec.into_boxed_slice())
401    }
402}
403
404impl<'de, T, Context> BorrowDecode<'de, Context> for Box<[T]>
405where
406    T: BorrowDecode<'de, Context> + 'de,
407{
408    fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
409        decoder: &mut D,
410    ) -> Result<Self, DecodeError> {
411        let vec = Vec::borrow_decode(decoder)?;
412        Ok(vec.into_boxed_slice())
413    }
414}
415
416impl<Context, T> Decode<Context> for Cow<'_, T>
417where
418    T: ToOwned + ?Sized,
419    <T as ToOwned>::Owned: Decode<Context>,
420{
421    fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
422        let t = <T as ToOwned>::Owned::decode(decoder)?;
423        Ok(Cow::Owned(t))
424    }
425}
426impl<'cow, T, Context> BorrowDecode<'cow, Context> for Cow<'cow, T>
427where
428    T: ToOwned + ?Sized,
429    &'cow T: BorrowDecode<'cow, Context>,
430{
431    fn borrow_decode<D: BorrowDecoder<'cow, Context = Context>>(
432        decoder: &mut D,
433    ) -> Result<Self, DecodeError> {
434        let t = <&T>::borrow_decode(decoder)?;
435        Ok(Cow::Borrowed(t))
436    }
437}
438
439impl<T> Encode for Cow<'_, T>
440where
441    T: ToOwned + ?Sized,
442    for<'a> &'a T: Encode,
443{
444    fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
445        self.as_ref().encode(encoder)
446    }
447}
448
449#[test]
450fn test_cow_round_trip() {
451    let start = Cow::Borrowed("Foo");
452    let encoded = crate::encode_to_vec(&start, crate::config::standard()).unwrap();
453    let (end, _) =
454        crate::borrow_decode_from_slice::<Cow<'_, str>, _>(&encoded, crate::config::standard())
455            .unwrap();
456    assert_eq!(start, end);
457    let (end, _) =
458        crate::decode_from_slice::<Cow<'_, str>, _>(&encoded, crate::config::standard()).unwrap();
459    assert_eq!(start, end);
460}
461
462impl<Context, T> Decode<Context> for Rc<T>
463where
464    T: Decode<Context>,
465{
466    fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
467        let t = T::decode(decoder)?;
468        Ok(Self::new(t))
469    }
470}
471
472impl<Context> Decode<Context> for Rc<str> {
473    fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
474        let string = String::decode(decoder)?;
475        Ok(string.into())
476    }
477}
478
479impl<'de, T, Context> BorrowDecode<'de, Context> for Rc<T>
480where
481    T: BorrowDecode<'de, Context>,
482{
483    fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
484        decoder: &mut D,
485    ) -> Result<Self, DecodeError> {
486        let t = T::borrow_decode(decoder)?;
487        Ok(Self::new(t))
488    }
489}
490
491impl<'de, Context> BorrowDecode<'de, Context> for Rc<str> {
492    fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
493        decoder: &mut D,
494    ) -> Result<Self, DecodeError> {
495        let string = String::decode(decoder)?;
496        Ok(string.into())
497    }
498}
499
500impl<T> Encode for Rc<T>
501where
502    T: Encode + ?Sized,
503{
504    fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
505        T::encode(self, encoder)
506    }
507}
508
509impl<Context, T> Decode<Context> for Rc<[T]>
510where
511    T: Decode<Context> + 'static,
512{
513    fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
514        let vec = Vec::decode(decoder)?;
515        Ok(vec.into())
516    }
517}
518
519impl<'de, T, Context> BorrowDecode<'de, Context> for Rc<[T]>
520where
521    T: BorrowDecode<'de, Context> + 'de,
522{
523    fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
524        decoder: &mut D,
525    ) -> Result<Self, DecodeError> {
526        let vec = Vec::borrow_decode(decoder)?;
527        Ok(vec.into())
528    }
529}
530
531#[cfg(target_has_atomic = "ptr")]
532impl<Context, T> Decode<Context> for Arc<T>
533where
534    T: Decode<Context>,
535{
536    fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
537        let t = T::decode(decoder)?;
538        Ok(Self::new(t))
539    }
540}
541
542#[cfg(target_has_atomic = "ptr")]
543impl<Context> Decode<Context> for Arc<str> {
544    fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
545        let string = String::decode(decoder)?;
546        Ok(string.into())
547    }
548}
549
550#[cfg(target_has_atomic = "ptr")]
551impl<'de, T, Context> BorrowDecode<'de, Context> for Arc<T>
552where
553    T: BorrowDecode<'de, Context>,
554{
555    fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
556        decoder: &mut D,
557    ) -> Result<Self, DecodeError> {
558        let t = T::borrow_decode(decoder)?;
559        Ok(Self::new(t))
560    }
561}
562
563#[cfg(target_has_atomic = "ptr")]
564impl<'de, Context> BorrowDecode<'de, Context> for Arc<str> {
565    fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
566        decoder: &mut D,
567    ) -> Result<Self, DecodeError> {
568        let string = String::decode(decoder)?;
569        Ok(string.into())
570    }
571}
572
573#[cfg(target_has_atomic = "ptr")]
574impl<T> Encode for Arc<T>
575where
576    T: Encode + ?Sized,
577{
578    fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
579        T::encode(self, encoder)
580    }
581}
582
583#[cfg(target_has_atomic = "ptr")]
584impl<Context, T> Decode<Context> for Arc<[T]>
585where
586    T: Decode<Context> + 'static,
587{
588    fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
589        let vec = Vec::decode(decoder)?;
590        Ok(vec.into())
591    }
592}
593
594#[cfg(target_has_atomic = "ptr")]
595impl<'de, T, Context> BorrowDecode<'de, Context> for Arc<[T]>
596where
597    T: BorrowDecode<'de, Context> + 'de,
598{
599    fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
600        decoder: &mut D,
601    ) -> Result<Self, DecodeError> {
602        let vec = Vec::borrow_decode(decoder)?;
603        Ok(vec.into())
604    }
605}