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}