bincode/features/
impl_alloc.rs

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