Skip to main content

bincode/de/
mod.rs

1//! Decoder-based structs and traits.
2
3mod decoder;
4mod impl_core;
5mod impl_tuples;
6mod impls;
7mod untrusted;
8mod untrusted_impls;
9
10pub use untrusted::{
11    BorrowDecodeUntrusted, BorrowUntrustedDecoder, DecodeUntrusted, UntrustedDecoder,
12};
13
14use self::{
15    decoder::WithContext,
16    read::{BorrowReader, Reader},
17};
18use crate::{
19    config::{Config, InternalLimitConfig},
20    error::DecodeError,
21    utils::Sealed,
22};
23
24pub mod read;
25
26pub use self::decoder::DecoderImpl;
27
28/// Trait that makes a type able to be decoded, akin to serde's `DeserializeOwned` trait.
29///
30/// Some types may require specific contexts. For example, to decode arena-based collections, an arena allocator must be provided as a context. In these cases, the context type `Context` should be specified or bounded.
31///
32/// This trait should be implemented for types which do not have references to data in the reader. For types that contain e.g. `&str` and `&[u8]`, implement [BorrowDecode] instead.
33///
34/// Whenever you derive `Decode` for your type, the base trait `BorrowDecode` is automatically implemented.
35///
36/// This trait will be automatically implemented with unbounded `Context` if you enable the `derive` feature and add `#[derive(bincode::Decode)]` to your type. Note that if the type contains any lifetimes, `BorrowDecode` will be implemented instead.
37///
38/// # Implementing this trait manually
39///
40/// If you want to implement this trait for your type, the easiest way is to add a `#[derive(bincode::Decode)]`, build and check your `target/generated/bincode/` folder. This should generate a `<Struct name>_Decode.rs` file.
41///
42/// For this struct:
43///
44/// ```
45/// struct Entity {
46///     pub x: f32,
47///     pub y: f32,
48/// }
49/// ```
50///
51/// It will look something like:
52///
53/// ```
54/// # struct Entity {
55/// #     pub x: f32,
56/// #     pub y: f32,
57/// # }
58/// impl<Context> bincode::Decode<Context> for Entity {
59///     fn decode<D: bincode::de::Decoder<Context = Context>>(
60///         decoder: &mut D,
61///     ) -> core::result::Result<Self, bincode::error::DecodeError> {
62///         Ok(Self {
63///             x: bincode::Decode::decode(decoder)?,
64///             y: bincode::Decode::decode(decoder)?,
65///         })
66///     }
67/// }
68/// impl<'de, Context> bincode::BorrowDecode<'de, Context> for Entity {
69///     fn borrow_decode<D: bincode::de::BorrowDecoder<'de, Context = Context>>(
70///         decoder: &mut D,
71///     ) -> core::result::Result<Self, bincode::error::DecodeError> {
72///         Ok(Self {
73///             x: bincode::BorrowDecode::borrow_decode(decoder)?,
74///             y: bincode::BorrowDecode::borrow_decode(decoder)?,
75///         })
76///     }
77/// }
78/// ```
79///
80/// From here you can add/remove fields, or add custom logic.
81///
82/// To get specific integer types, you can use:
83/// ```
84/// # struct Foo;
85/// # impl<Context> bincode::Decode<Context> for Foo {
86/// #     fn decode<D: bincode::de::Decoder<Context = Context>>(
87/// #         decoder: &mut D,
88/// #     ) -> core::result::Result<Self, bincode::error::DecodeError> {
89/// let x: u8 = bincode::Decode::<Context>::decode(decoder)?;
90/// let x = <u8 as bincode::Decode::<Context>>::decode(decoder)?;
91/// #         Ok(Foo)
92/// #     }
93/// # }
94/// # bincode::impl_borrow_decode!(Foo);
95/// ```
96///
97/// You can use `Context` to require contexts for decoding a type:
98/// ```
99/// # /// # use bumpalo::Bump;
100/// use bincode::de::Decoder;
101/// use bincode::error::DecodeError;
102/// struct BytesInArena<'a>(bumpalo::collections::Vec<'a, u8>);
103/// impl<'a> bincode::Decode<&'a bumpalo::Bump> for BytesInArena<'a> {
104/// fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
105///         todo!()
106///     }
107/// # }
108/// ```
109pub trait Decode<Context>: Sized {
110    /// Attempt to decode this type with the given [Decode].
111    fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError>;
112}
113
114/// Trait that makes a type able to be decoded, akin to serde's `Deserialize` trait.
115///
116/// This trait should be implemented for types that contain borrowed data, like `&str` and `&[u8]`. If your type does not have borrowed data, consider implementing [Decode] instead.
117///
118/// This trait will be automatically implemented if you enable the `derive` feature and add `#[derive(bincode::Decode)]` to a type with a lifetime.
119pub trait BorrowDecode<'de, Context>: Sized {
120    /// Attempt to decode this type with the given [BorrowDecode].
121    fn borrow_decode<D: BorrowDecoder<'de, Context = Context>>(
122        decoder: &mut D,
123    ) -> Result<Self, DecodeError>;
124}
125
126/// Helper macro to implement `BorrowDecode` for any type that implements `Decode`.
127#[macro_export]
128macro_rules! impl_borrow_decode {
129    ($ty:ty $(, $param:tt)*) => {
130        impl<'de $(, $param)*, __Context> $crate::BorrowDecode<'de, __Context> for $ty {
131            fn borrow_decode<D: $crate::de::BorrowDecoder<'de, Context = __Context>>(
132                decoder: &mut D,
133            ) -> core::result::Result<Self, $crate::error::DecodeError> {
134                $crate::Decode::decode(decoder)
135            }
136        }
137    };
138}
139
140/// Helper macro to implement `BorrowDecode` for any type that implements `Decode`.
141#[macro_export]
142macro_rules! impl_borrow_decode_with_context {
143    ($ty:ty, $context:ty $(, $param:tt)*) => {
144        impl<'de $(, $param)*> $crate::BorrowDecode<'de, $context> for $ty {
145            fn borrow_decode<D: $crate::de::BorrowDecoder<'de, Context = $context>>(
146                decoder: &mut D,
147            ) -> core::result::Result<Self, $crate::error::DecodeError> {
148                $crate::Decode::decode(decoder)
149            }
150        }
151    };
152}
153
154/// Any source that can decode basic types. This type is most notably implemented for [Decoder].
155pub trait Decoder: Sealed {
156    /// The concrete [Reader] type
157    type R: Reader;
158
159    /// The concrete [Config] type
160    type C: Config;
161
162    /// The decoding context type
163    type Context;
164
165    /// Returns the decoding context
166    fn context(&mut self) -> &mut Self::Context;
167
168    /// Wraps decoder with a context
169    fn with_context<C>(&mut self, context: C) -> WithContext<Self, C> {
170        WithContext {
171            decoder: self,
172            context,
173        }
174    }
175
176    /// Returns a mutable reference to the reader
177    fn reader(&mut self) -> &mut Self::R;
178
179    /// Returns a reference to the config
180    fn config(&self) -> &Self::C;
181
182    /// Claim that `n` bytes are going to be read from the decoder.
183    /// This can be used to validate `Configuration::Limit<N>()`.
184    fn claim_bytes_read(&mut self, n: usize) -> Result<(), DecodeError>;
185
186    /// Claim that we're going to read a container which contains `len` entries of `T`.
187    /// This will correctly handle overflowing if `len * size_of::<T>() > usize::max_value`
188    fn claim_container_read<T>(&mut self, len: usize) -> Result<(), DecodeError> {
189        if <Self::C as InternalLimitConfig>::LIMIT.is_some() {
190            match len.checked_mul(core::mem::size_of::<T>()) {
191                Some(val) => self.claim_bytes_read(val),
192                None => Err(DecodeError::LimitExceeded),
193            }
194        } else {
195            Ok(())
196        }
197    }
198
199    /// Notify the decoder that `n` bytes are being reclaimed.
200    ///
201    /// When decoding container types, a typical implementation would claim to read `len * size_of::<T>()` bytes.
202    /// This is to ensure that bincode won't allocate several GB of memory while constructing the container.
203    ///
204    /// Because the implementation claims `len * size_of::<T>()`, but then has to decode each `T`, this would be marked
205    /// as double. This function allows us to un-claim each `T` that gets decoded.
206    ///
207    /// We cannot check if `len * size_of::<T>()` is valid without claiming it, because this would mean that if you have
208    /// a nested container (e.g. `Vec<Vec<T>>`), it does not know how much memory is already claimed, and could easily
209    /// allocate much more than the user intends.
210    /// ```
211    /// # use bincode::de::{Decode, Decoder};
212    /// # use bincode::error::DecodeError;
213    /// # struct Container<T>(Vec<T>);
214    /// # impl<T> Container<T> {
215    /// #     fn with_capacity(cap: usize) -> Self {
216    /// #         Self(Vec::with_capacity(cap))
217    /// #     }
218    /// #     
219    /// #     fn push(&mut self, t: T) {
220    /// #         self.0.push(t);
221    /// #     }
222    /// # }
223    /// impl<Context, T: Decode<Context>> Decode<Context> for Container<T> {
224    ///     fn decode<D: Decoder<Context = Context>>(decoder: &mut D) -> Result<Self, DecodeError> {
225    ///         let len = u64::decode(decoder)?;
226    ///         let len: usize = len.try_into().map_err(|_| DecodeError::OutsideUsizeRange(len))?;
227    ///         // Make sure we don't allocate too much memory
228    ///         decoder.claim_bytes_read(len * core::mem::size_of::<T>());
229    ///
230    ///         let mut result = Container::with_capacity(len);
231    ///         for _ in 0..len {
232    ///             // un-claim the memory
233    ///             decoder.unclaim_bytes_read(core::mem::size_of::<T>());
234    ///             result.push(T::decode(decoder)?)
235    ///         }
236    ///         Ok(result)
237    ///     }
238    /// }
239    /// impl<'de, Context, T: bincode::BorrowDecode<'de, Context>> bincode::BorrowDecode<'de, Context> for Container<T> {
240    ///     fn borrow_decode<D: bincode::de::BorrowDecoder<'de, Context = Context>>(
241    ///         decoder: &mut D,
242    ///     ) -> core::result::Result<Self, bincode::error::DecodeError> {
243    ///         let len = u64::borrow_decode(decoder)?;
244    ///         let len: usize = len.try_into().map_err(|_| DecodeError::OutsideUsizeRange(len))?;
245    ///         // Make sure we don't allocate too much memory
246    ///         decoder.claim_bytes_read(len * core::mem::size_of::<T>());
247    ///
248    ///         let mut result = Container::with_capacity(len);
249    ///         for _ in 0..len {
250    ///             // un-claim the memory
251    ///             decoder.unclaim_bytes_read(core::mem::size_of::<T>());
252    ///             result.push(T::borrow_decode(decoder)?)
253    ///         }
254    ///         Ok(result)
255    ///     }
256    /// }
257    /// ```
258    fn unclaim_bytes_read(&mut self, n: usize);
259}
260
261/// Any source that can decode basic types. This type is most notably implemented for [Decoder].
262///
263/// This is an extension of [Decode] that can also return borrowed data.
264pub trait BorrowDecoder<'de>: Decoder {
265    /// The concrete [BorrowReader] type
266    type BR: BorrowReader<'de>;
267
268    /// Rerturns a mutable reference to the borrow reader
269    fn borrow_reader(&mut self) -> &mut Self::BR;
270}
271
272impl<T> Decoder for &mut T
273where
274    T: Decoder,
275{
276    type R = T::R;
277
278    type C = T::C;
279
280    type Context = T::Context;
281
282    fn reader(&mut self) -> &mut Self::R {
283        T::reader(self)
284    }
285
286    fn config(&self) -> &Self::C {
287        T::config(self)
288    }
289
290    #[inline]
291    fn claim_bytes_read(&mut self, n: usize) -> Result<(), DecodeError> {
292        T::claim_bytes_read(self, n)
293    }
294
295    #[inline]
296    fn unclaim_bytes_read(&mut self, n: usize) {
297        T::unclaim_bytes_read(self, n)
298    }
299
300    fn context(&mut self) -> &mut Self::Context {
301        T::context(self)
302    }
303}
304
305impl<T: UntrustedDecoder> UntrustedDecoder for &mut T {}
306
307impl<'de, T> BorrowDecoder<'de> for &mut T
308where
309    T: BorrowDecoder<'de>,
310{
311    type BR = T::BR;
312
313    fn borrow_reader(&mut self) -> &mut Self::BR {
314        T::borrow_reader(self)
315    }
316}
317
318/// Decodes only the option variant from the decoder. Will not read any more data than that.
319#[inline]
320pub(crate) fn decode_option_variant<D: Decoder>(
321    decoder: &mut D,
322    type_name: &'static str,
323) -> Result<Option<()>, DecodeError> {
324    let is_some = u8::decode(decoder)?;
325    match is_some {
326        0 => Ok(None),
327        1 => Ok(Some(())),
328        x => Err(DecodeError::UnexpectedVariant {
329            found: x as u32,
330            allowed: &crate::error::AllowedEnumVariants::Range { max: 1, min: 0 },
331            type_name,
332        }),
333    }
334}
335
336/// Decodes the length of any slice, container, etc from the decoder
337#[inline]
338pub(crate) fn decode_slice_len<D: Decoder>(decoder: &mut D) -> Result<usize, DecodeError> {
339    let v = u64::decode(decoder)?;
340
341    v.try_into().map_err(|_| DecodeError::OutsideUsizeRange(v))
342}