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