1 | use core::marker::PhantomData; |
2 | use core::mem::MaybeUninit; |
3 | use core::{ |
4 | convert::{TryFrom, TryInto}, |
5 | mem::size_of, |
6 | }; |
7 | |
8 | #[cfg (feature = "bytes" )] |
9 | use bytes::{BufMut, BytesMut}; |
10 | |
11 | use crate::__private::maybestd::{ |
12 | borrow::{Borrow, Cow, ToOwned}, |
13 | boxed::Box, |
14 | collections::{BTreeMap, BTreeSet, LinkedList, VecDeque}, |
15 | format, |
16 | string::{String, ToString}, |
17 | vec, |
18 | vec::Vec, |
19 | }; |
20 | use crate::io::{Error, ErrorKind, Read, Result}; |
21 | |
22 | use crate::error::check_zst; |
23 | |
24 | mod hint; |
25 | |
26 | const ERROR_NOT_ALL_BYTES_READ: &str = "Not all bytes read" ; |
27 | const ERROR_UNEXPECTED_LENGTH_OF_INPUT: &str = "Unexpected length of input" ; |
28 | const ERROR_OVERFLOW_ON_MACHINE_WITH_32_BIT_ISIZE: &str = "Overflow on machine with 32 bit isize" ; |
29 | const ERROR_OVERFLOW_ON_MACHINE_WITH_32_BIT_USIZE: &str = "Overflow on machine with 32 bit usize" ; |
30 | const ERROR_INVALID_ZERO_VALUE: &str = "Expected a non-zero value" ; |
31 | |
32 | #[cfg (feature = "de_strict_order" )] |
33 | const ERROR_WRONG_ORDER_OF_KEYS: &str = "keys were not serialized in ascending order" ; |
34 | |
35 | /// A data-structure that can be de-serialized from binary format by NBOR. |
36 | pub trait BorshDeserialize: Sized { |
37 | /// Deserializes this instance from a given slice of bytes. |
38 | /// Updates the buffer to point at the remaining bytes. |
39 | fn deserialize(buf: &mut &[u8]) -> Result<Self> { |
40 | Self::deserialize_reader(&mut *buf) |
41 | } |
42 | |
43 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self>; |
44 | |
45 | /// Deserialize this instance from a slice of bytes. |
46 | fn try_from_slice(v: &[u8]) -> Result<Self> { |
47 | let mut v_mut = v; |
48 | let result = Self::deserialize(&mut v_mut)?; |
49 | if !v_mut.is_empty() { |
50 | return Err(Error::new(ErrorKind::InvalidData, ERROR_NOT_ALL_BYTES_READ)); |
51 | } |
52 | Ok(result) |
53 | } |
54 | |
55 | fn try_from_reader<R: Read>(reader: &mut R) -> Result<Self> { |
56 | let result = Self::deserialize_reader(reader)?; |
57 | let mut buf = [0u8; 1]; |
58 | match reader.read_exact(&mut buf) { |
59 | Err(f) if f.kind() == ErrorKind::UnexpectedEof => Ok(result), |
60 | _ => Err(Error::new(ErrorKind::InvalidData, ERROR_NOT_ALL_BYTES_READ)), |
61 | } |
62 | } |
63 | |
64 | #[inline ] |
65 | #[doc (hidden)] |
66 | fn vec_from_reader<R: Read>(len: u32, reader: &mut R) -> Result<Option<Vec<Self>>> { |
67 | let _ = len; |
68 | let _ = reader; |
69 | Ok(None) |
70 | } |
71 | |
72 | #[inline ] |
73 | #[doc (hidden)] |
74 | fn array_from_reader<R: Read, const N: usize>(reader: &mut R) -> Result<Option<[Self; N]>> { |
75 | let _ = reader; |
76 | Ok(None) |
77 | } |
78 | } |
79 | |
80 | /// Additional methods offered on enums which is used by `[derive(BorshDeserialize)]`. |
81 | pub trait EnumExt: BorshDeserialize { |
82 | /// Deserialises given variant of an enum from the reader. |
83 | /// |
84 | /// This may be used to perform validation or filtering based on what |
85 | /// variant is being deserialised. |
86 | /// |
87 | /// ``` |
88 | /// use borsh::BorshDeserialize; |
89 | /// use borsh::de::EnumExt as _; |
90 | /// |
91 | /// /// derive is only available if borsh is built with `features = ["derive"]` |
92 | /// # #[cfg (feature = "derive" )] |
93 | /// #[derive(Debug, PartialEq, Eq, BorshDeserialize)] |
94 | /// enum MyEnum { |
95 | /// Zero, |
96 | /// One(u8), |
97 | /// Many(Vec<u8>) |
98 | /// } |
99 | /// |
100 | /// # #[cfg (feature = "derive" )] |
101 | /// #[derive(Debug, PartialEq, Eq)] |
102 | /// struct OneOrZero(MyEnum); |
103 | /// |
104 | /// # #[cfg (feature = "derive" )] |
105 | /// impl borsh::de::BorshDeserialize for OneOrZero { |
106 | /// fn deserialize_reader<R: borsh::io::Read>( |
107 | /// reader: &mut R, |
108 | /// ) -> borsh::io::Result<Self> { |
109 | /// use borsh::de::EnumExt; |
110 | /// let tag = u8::deserialize_reader(reader)?; |
111 | /// if tag == 2 { |
112 | /// Err(borsh::io::Error::new( |
113 | /// borsh::io::ErrorKind::InvalidData, |
114 | /// "MyEnum::Many not allowed here" , |
115 | /// )) |
116 | /// } else { |
117 | /// MyEnum::deserialize_variant(reader, tag).map(Self) |
118 | /// } |
119 | /// } |
120 | /// } |
121 | /// |
122 | /// use borsh::from_slice; |
123 | /// let data = b" \0" ; |
124 | /// # #[cfg (feature = "derive" )] |
125 | /// assert_eq!(MyEnum::Zero, from_slice::<MyEnum>(&data[..]).unwrap()); |
126 | /// # #[cfg (feature = "derive" )] |
127 | /// assert_eq!(MyEnum::Zero, from_slice::<OneOrZero>(&data[..]).unwrap().0); |
128 | /// |
129 | /// let data = b" \x02\0\0\0\0" ; |
130 | /// # #[cfg (feature = "derive" )] |
131 | /// assert_eq!(MyEnum::Many(Vec::new()), from_slice::<MyEnum>(&data[..]).unwrap()); |
132 | /// # #[cfg (feature = "derive" )] |
133 | /// assert!(from_slice::<OneOrZero>(&data[..]).is_err()); |
134 | /// ``` |
135 | fn deserialize_variant<R: Read>(reader: &mut R, tag: u8) -> Result<Self>; |
136 | } |
137 | |
138 | fn unexpected_eof_to_unexpected_length_of_input(e: Error) -> Error { |
139 | if e.kind() == ErrorKind::UnexpectedEof { |
140 | Error::new(kind:ErrorKind::InvalidData, ERROR_UNEXPECTED_LENGTH_OF_INPUT) |
141 | } else { |
142 | e |
143 | } |
144 | } |
145 | |
146 | impl BorshDeserialize for u8 { |
147 | #[inline ] |
148 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
149 | let mut buf = [0u8; 1]; |
150 | reader |
151 | .read_exact(&mut buf) |
152 | .map_err(unexpected_eof_to_unexpected_length_of_input)?; |
153 | Ok(buf[0]) |
154 | } |
155 | |
156 | #[inline ] |
157 | #[doc (hidden)] |
158 | fn vec_from_reader<R: Read>(len: u32, reader: &mut R) -> Result<Option<Vec<Self>>> { |
159 | let len: usize = len.try_into().map_err(|_| ErrorKind::InvalidData)?; |
160 | // Avoid OOM by limiting the size of allocation. This makes the read |
161 | // less efficient (since we need to loop and reallocate) but it protects |
162 | // us from someone sending us [0xff, 0xff, 0xff, 0xff] and forcing us to |
163 | // allocate 4GiB of memory. |
164 | let mut vec = vec![0u8; len.min(1024 * 1024)]; |
165 | let mut pos = 0; |
166 | while pos < len { |
167 | if pos == vec.len() { |
168 | vec.resize(vec.len().saturating_mul(2).min(len), 0) |
169 | } |
170 | // TODO(mina86): Convert this to read_buf once that stabilises. |
171 | match reader.read(&mut vec.as_mut_slice()[pos..])? { |
172 | 0 => { |
173 | return Err(Error::new( |
174 | ErrorKind::InvalidData, |
175 | ERROR_UNEXPECTED_LENGTH_OF_INPUT, |
176 | )) |
177 | } |
178 | read => { |
179 | pos += read; |
180 | } |
181 | } |
182 | } |
183 | Ok(Some(vec)) |
184 | } |
185 | |
186 | #[inline ] |
187 | #[doc (hidden)] |
188 | fn array_from_reader<R: Read, const N: usize>(reader: &mut R) -> Result<Option<[Self; N]>> { |
189 | let mut arr = [0u8; N]; |
190 | reader |
191 | .read_exact(&mut arr) |
192 | .map_err(unexpected_eof_to_unexpected_length_of_input)?; |
193 | Ok(Some(arr)) |
194 | } |
195 | } |
196 | |
197 | macro_rules! impl_for_integer { |
198 | ($type: ident) => { |
199 | impl BorshDeserialize for $type { |
200 | #[inline] |
201 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
202 | let mut buf = [0u8; size_of::<$type>()]; |
203 | reader |
204 | .read_exact(&mut buf) |
205 | .map_err(unexpected_eof_to_unexpected_length_of_input)?; |
206 | let res = $type::from_le_bytes(buf.try_into().unwrap()); |
207 | Ok(res) |
208 | } |
209 | } |
210 | }; |
211 | } |
212 | |
213 | impl_for_integer!(i8); |
214 | impl_for_integer!(i16); |
215 | impl_for_integer!(i32); |
216 | impl_for_integer!(i64); |
217 | impl_for_integer!(i128); |
218 | impl_for_integer!(u16); |
219 | impl_for_integer!(u32); |
220 | impl_for_integer!(u64); |
221 | impl_for_integer!(u128); |
222 | |
223 | macro_rules! impl_for_nonzero_integer { |
224 | ($type: ty) => { |
225 | impl BorshDeserialize for $type { |
226 | #[inline] |
227 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
228 | <$type>::new(BorshDeserialize::deserialize_reader(reader)?) |
229 | .ok_or_else(|| Error::new(ErrorKind::InvalidData, ERROR_INVALID_ZERO_VALUE)) |
230 | } |
231 | } |
232 | }; |
233 | } |
234 | |
235 | impl_for_nonzero_integer!(core::num::NonZeroI8); |
236 | impl_for_nonzero_integer!(core::num::NonZeroI16); |
237 | impl_for_nonzero_integer!(core::num::NonZeroI32); |
238 | impl_for_nonzero_integer!(core::num::NonZeroI64); |
239 | impl_for_nonzero_integer!(core::num::NonZeroI128); |
240 | impl_for_nonzero_integer!(core::num::NonZeroU8); |
241 | impl_for_nonzero_integer!(core::num::NonZeroU16); |
242 | impl_for_nonzero_integer!(core::num::NonZeroU32); |
243 | impl_for_nonzero_integer!(core::num::NonZeroU64); |
244 | impl_for_nonzero_integer!(core::num::NonZeroU128); |
245 | impl_for_nonzero_integer!(core::num::NonZeroUsize); |
246 | |
247 | impl BorshDeserialize for isize { |
248 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
249 | let i: i64 = BorshDeserialize::deserialize_reader(reader)?; |
250 | let i: isize = isize::try_from(i).map_err(|_| { |
251 | Error::new( |
252 | kind:ErrorKind::InvalidData, |
253 | ERROR_OVERFLOW_ON_MACHINE_WITH_32_BIT_ISIZE, |
254 | ) |
255 | })?; |
256 | Ok(i) |
257 | } |
258 | } |
259 | |
260 | impl BorshDeserialize for usize { |
261 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
262 | let u: u64 = BorshDeserialize::deserialize_reader(reader)?; |
263 | let u: usize = usize::try_from(u).map_err(|_| { |
264 | Error::new( |
265 | kind:ErrorKind::InvalidData, |
266 | ERROR_OVERFLOW_ON_MACHINE_WITH_32_BIT_USIZE, |
267 | ) |
268 | })?; |
269 | Ok(u) |
270 | } |
271 | } |
272 | |
273 | // Note NaNs have a portability issue. Specifically, signalling NaNs on MIPS are quiet NaNs on x86, |
274 | // and vice-versa. We disallow NaNs to avoid this issue. |
275 | macro_rules! impl_for_float { |
276 | ($type: ident, $int_type: ident) => { |
277 | impl BorshDeserialize for $type { |
278 | #[inline] |
279 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
280 | let mut buf = [0u8; size_of::<$type>()]; |
281 | reader |
282 | .read_exact(&mut buf) |
283 | .map_err(unexpected_eof_to_unexpected_length_of_input)?; |
284 | let res = $type::from_bits($int_type::from_le_bytes(buf.try_into().unwrap())); |
285 | if res.is_nan() { |
286 | return Err(Error::new( |
287 | ErrorKind::InvalidData, |
288 | "For portability reasons we do not allow to deserialize NaNs." , |
289 | )); |
290 | } |
291 | Ok(res) |
292 | } |
293 | } |
294 | }; |
295 | } |
296 | |
297 | impl_for_float!(f32, u32); |
298 | impl_for_float!(f64, u64); |
299 | |
300 | impl BorshDeserialize for bool { |
301 | #[inline ] |
302 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
303 | let b: u8 = BorshDeserialize::deserialize_reader(reader)?; |
304 | if b == 0 { |
305 | Ok(false) |
306 | } else if b == 1 { |
307 | Ok(true) |
308 | } else { |
309 | let msg: String = format!("Invalid bool representation: {}" , b); |
310 | |
311 | Err(Error::new(kind:ErrorKind::InvalidData, error:msg)) |
312 | } |
313 | } |
314 | } |
315 | |
316 | impl<T> BorshDeserialize for Option<T> |
317 | where |
318 | T: BorshDeserialize, |
319 | { |
320 | #[inline ] |
321 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
322 | let flag: u8 = BorshDeserialize::deserialize_reader(reader)?; |
323 | if flag == 0 { |
324 | Ok(None) |
325 | } else if flag == 1 { |
326 | Ok(Some(T::deserialize_reader(reader)?)) |
327 | } else { |
328 | let msg: String = format!( |
329 | "Invalid Option representation: {}. The first byte must be 0 or 1" , |
330 | flag |
331 | ); |
332 | |
333 | Err(Error::new(kind:ErrorKind::InvalidData, error:msg)) |
334 | } |
335 | } |
336 | } |
337 | |
338 | impl<T, E> BorshDeserialize for core::result::Result<T, E> |
339 | where |
340 | T: BorshDeserialize, |
341 | E: BorshDeserialize, |
342 | { |
343 | #[inline ] |
344 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
345 | let flag: u8 = BorshDeserialize::deserialize_reader(reader)?; |
346 | if flag == 0 { |
347 | Ok(Err(E::deserialize_reader(reader)?)) |
348 | } else if flag == 1 { |
349 | Ok(Ok(T::deserialize_reader(reader)?)) |
350 | } else { |
351 | let msg: String = format!( |
352 | "Invalid Result representation: {}. The first byte must be 0 or 1" , |
353 | flag |
354 | ); |
355 | |
356 | Err(Error::new(kind:ErrorKind::InvalidData, error:msg)) |
357 | } |
358 | } |
359 | } |
360 | |
361 | impl BorshDeserialize for String { |
362 | #[inline ] |
363 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
364 | String::from_utf8(Vec::<u8>::deserialize_reader(reader)?).map_err(|err: FromUtf8Error| { |
365 | let msg: String = err.to_string(); |
366 | Error::new(kind:ErrorKind::InvalidData, error:msg) |
367 | }) |
368 | } |
369 | } |
370 | |
371 | /// Module is available if borsh is built with `features = ["ascii"]`. |
372 | #[cfg (feature = "ascii" )] |
373 | pub mod ascii { |
374 | //! |
375 | //! Module defines [BorshDeserialize] implementation for |
376 | //! some types from [ascii](::ascii) crate. |
377 | use crate::BorshDeserialize; |
378 | use crate::__private::maybestd::{string::ToString, vec::Vec}; |
379 | use crate::io::{Error, ErrorKind, Read, Result}; |
380 | |
381 | impl BorshDeserialize for ascii::AsciiString { |
382 | #[inline ] |
383 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
384 | let bytes = Vec::<u8>::deserialize_reader(reader)?; |
385 | ascii::AsciiString::from_ascii(bytes) |
386 | .map_err(|err| Error::new(ErrorKind::InvalidData, err.to_string())) |
387 | } |
388 | } |
389 | |
390 | impl BorshDeserialize for ascii::AsciiChar { |
391 | #[inline ] |
392 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
393 | let byte = u8::deserialize_reader(reader)?; |
394 | ascii::AsciiChar::from_ascii(byte) |
395 | .map_err(|err| Error::new(ErrorKind::InvalidData, err.to_string())) |
396 | } |
397 | } |
398 | } |
399 | |
400 | impl<T> BorshDeserialize for Vec<T> |
401 | where |
402 | T: BorshDeserialize, |
403 | { |
404 | #[inline ] |
405 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
406 | check_zst::<T>()?; |
407 | |
408 | let len: u32 = u32::deserialize_reader(reader)?; |
409 | if len == 0 { |
410 | Ok(Vec::new()) |
411 | } else if let Some(vec_bytes: Vec) = T::vec_from_reader(len, reader)? { |
412 | Ok(vec_bytes) |
413 | } else { |
414 | // TODO(16): return capacity allocation when we can safely do that. |
415 | let mut result: Vec = Vec::with_capacity(hint::cautious::<T>(hint:len)); |
416 | for _ in 0..len { |
417 | result.push(T::deserialize_reader(reader)?); |
418 | } |
419 | Ok(result) |
420 | } |
421 | } |
422 | } |
423 | |
424 | #[cfg (feature = "bytes" )] |
425 | impl BorshDeserialize for bytes::Bytes { |
426 | #[inline ] |
427 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
428 | let vec = <Vec<u8>>::deserialize_reader(reader)?; |
429 | Ok(vec.into()) |
430 | } |
431 | } |
432 | |
433 | #[cfg (feature = "bytes" )] |
434 | impl BorshDeserialize for bytes::BytesMut { |
435 | #[inline ] |
436 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
437 | let len = u32::deserialize_reader(reader)?; |
438 | let mut out = BytesMut::with_capacity(hint::cautious::<u8>(len)); |
439 | for _ in 0..len { |
440 | out.put_u8(u8::deserialize_reader(reader)?); |
441 | } |
442 | Ok(out) |
443 | } |
444 | } |
445 | |
446 | #[cfg (feature = "bson" )] |
447 | impl BorshDeserialize for bson::oid::ObjectId { |
448 | #[inline ] |
449 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
450 | let mut buf = [0u8; 12]; |
451 | reader.read_exact(&mut buf)?; |
452 | Ok(bson::oid::ObjectId::from_bytes(buf)) |
453 | } |
454 | } |
455 | |
456 | #[cfg (feature = "indexmap" )] |
457 | // Taken from https://github.com/indexmap-rs/indexmap/blob/dd06e5773e4f91748396c67d00c83637f5c0dd49/src/borsh.rs#L39 |
458 | // license: MIT OR Apache-2.0 |
459 | impl<K, V, S> BorshDeserialize for indexmap::IndexMap<K, V, S> |
460 | where |
461 | K: BorshDeserialize + Eq + core::hash::Hash, |
462 | V: BorshDeserialize, |
463 | S: core::hash::BuildHasher + Default, |
464 | { |
465 | #[inline ] |
466 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
467 | check_zst::<K>()?; |
468 | let vec = <Vec<(K, V)>>::deserialize_reader(reader)?; |
469 | Ok(vec.into_iter().collect::<indexmap::IndexMap<K, V, S>>()) |
470 | } |
471 | } |
472 | |
473 | #[cfg (feature = "indexmap" )] |
474 | // Taken from https://github.com/indexmap-rs/indexmap/blob/dd06e5773e4f91748396c67d00c83637f5c0dd49/src/borsh.rs#L75 |
475 | // license: MIT OR Apache-2.0 |
476 | impl<T, S> BorshDeserialize for indexmap::IndexSet<T, S> |
477 | where |
478 | T: BorshDeserialize + Eq + core::hash::Hash, |
479 | S: core::hash::BuildHasher + Default, |
480 | { |
481 | #[inline ] |
482 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
483 | check_zst::<T>()?; |
484 | let vec = <Vec<T>>::deserialize_reader(reader)?; |
485 | Ok(vec.into_iter().collect::<indexmap::IndexSet<T, S>>()) |
486 | } |
487 | } |
488 | |
489 | impl<T> BorshDeserialize for Cow<'_, T> |
490 | where |
491 | T: ToOwned + ?Sized, |
492 | T::Owned: BorshDeserialize, |
493 | { |
494 | #[inline ] |
495 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
496 | Ok(Cow::Owned(BorshDeserialize::deserialize_reader(reader)?)) |
497 | } |
498 | } |
499 | |
500 | impl<T> BorshDeserialize for VecDeque<T> |
501 | where |
502 | T: BorshDeserialize, |
503 | { |
504 | #[inline ] |
505 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
506 | let vec: Vec = <Vec<T>>::deserialize_reader(reader)?; |
507 | Ok(vec.into()) |
508 | } |
509 | } |
510 | |
511 | impl<T> BorshDeserialize for LinkedList<T> |
512 | where |
513 | T: BorshDeserialize, |
514 | { |
515 | #[inline ] |
516 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
517 | let vec: Vec = <Vec<T>>::deserialize_reader(reader)?; |
518 | Ok(vec.into_iter().collect::<LinkedList<T>>()) |
519 | } |
520 | } |
521 | |
522 | /// Module is available if borsh is built with `features = ["std"]` or `features = ["hashbrown"]`. |
523 | /// |
524 | /// Module defines [BorshDeserialize] implementation for |
525 | /// [HashMap](std::collections::HashMap)/[HashSet](std::collections::HashSet). |
526 | #[cfg (hash_collections)] |
527 | pub mod hashes { |
528 | use core::hash::{BuildHasher, Hash}; |
529 | |
530 | use crate::BorshDeserialize; |
531 | use crate::__private::maybestd::collections::{HashMap, HashSet}; |
532 | use crate::__private::maybestd::vec::Vec; |
533 | use crate::io::{Read, Result}; |
534 | |
535 | #[cfg (feature = "de_strict_order" )] |
536 | const ERROR_WRONG_ORDER_OF_KEYS: &str = "keys were not serialized in ascending order" ; |
537 | use crate::error::check_zst; |
538 | #[cfg (feature = "de_strict_order" )] |
539 | use crate::io::{Error, ErrorKind}; |
540 | |
541 | impl<T, H> BorshDeserialize for HashSet<T, H> |
542 | where |
543 | T: BorshDeserialize + Eq + Hash + Ord, |
544 | H: BuildHasher + Default, |
545 | { |
546 | #[inline ] |
547 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
548 | // NOTE: deserialize-as-you-go approach as once was in HashSet is better in the sense |
549 | // that it allows to fail early, and not allocate memory for all the elements |
550 | // which may fail `cmp()` checks |
551 | // NOTE: deserialize first to `Vec<T>` is faster |
552 | let vec = <Vec<T>>::deserialize_reader(reader)?; |
553 | |
554 | #[cfg (feature = "de_strict_order" )] |
555 | // TODO: replace with `is_sorted` api when stabilizes https://github.com/rust-lang/rust/issues/53485 |
556 | // TODO: first replace with `array_windows` api when stabilizes https://github.com/rust-lang/rust/issues/75027 |
557 | for pair in vec.windows(2) { |
558 | let [a, b] = pair else { |
559 | unreachable!("`windows` always return a slice of length 2 or nothing" ); |
560 | }; |
561 | let cmp_result = a.cmp(b).is_lt(); |
562 | if !cmp_result { |
563 | return Err(Error::new( |
564 | ErrorKind::InvalidData, |
565 | ERROR_WRONG_ORDER_OF_KEYS, |
566 | )); |
567 | } |
568 | } |
569 | |
570 | Ok(vec.into_iter().collect::<HashSet<T, H>>()) |
571 | } |
572 | } |
573 | |
574 | impl<K, V, H> BorshDeserialize for HashMap<K, V, H> |
575 | where |
576 | K: BorshDeserialize + Eq + Hash + Ord, |
577 | V: BorshDeserialize, |
578 | H: BuildHasher + Default, |
579 | { |
580 | #[inline ] |
581 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
582 | check_zst::<K>()?; |
583 | // NOTE: deserialize-as-you-go approach as once was in HashSet is better in the sense |
584 | // that it allows to fail early, and not allocate memory for all the entries |
585 | // which may fail `cmp()` checks |
586 | // NOTE: deserialize first to `Vec<(K, V)>` is faster |
587 | let vec = <Vec<(K, V)>>::deserialize_reader(reader)?; |
588 | |
589 | #[cfg (feature = "de_strict_order" )] |
590 | // TODO: replace with `is_sorted` api when stabilizes https://github.com/rust-lang/rust/issues/53485 |
591 | // TODO: first replace with `array_windows` api when stabilizes https://github.com/rust-lang/rust/issues/75027 |
592 | for pair in vec.windows(2) { |
593 | let [(a_k, _a_v), (b_k, _b_v)] = pair else { |
594 | unreachable!("`windows` always return a slice of length 2 or nothing" ); |
595 | }; |
596 | let cmp_result = a_k.cmp(b_k).is_lt(); |
597 | if !cmp_result { |
598 | return Err(Error::new( |
599 | ErrorKind::InvalidData, |
600 | ERROR_WRONG_ORDER_OF_KEYS, |
601 | )); |
602 | } |
603 | } |
604 | |
605 | Ok(vec.into_iter().collect::<HashMap<K, V, H>>()) |
606 | } |
607 | } |
608 | } |
609 | |
610 | impl<T> BorshDeserialize for BTreeSet<T> |
611 | where |
612 | T: BorshDeserialize + Ord, |
613 | { |
614 | #[inline ] |
615 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
616 | // NOTE: deserialize-as-you-go approach as once was in HashSet is better in the sense |
617 | // that it allows to fail early, and not allocate memory for all the elements |
618 | // which may fail `cmp()` checks |
619 | // NOTE: deserialize first to `Vec<T>` is faster |
620 | let vec = <Vec<T>>::deserialize_reader(reader)?; |
621 | |
622 | #[cfg (feature = "de_strict_order" )] |
623 | // TODO: replace with `is_sorted` api when stabilizes https://github.com/rust-lang/rust/issues/53485 |
624 | // TODO: first replace with `array_windows` api when stabilizes https://github.com/rust-lang/rust/issues/75027 |
625 | for pair in vec.windows(2) { |
626 | let [a, b] = pair else { |
627 | unreachable!("`windows` always return a slice of length 2 or nothing" ); |
628 | }; |
629 | let cmp_result = a.cmp(b).is_lt(); |
630 | if !cmp_result { |
631 | return Err(Error::new( |
632 | ErrorKind::InvalidData, |
633 | ERROR_WRONG_ORDER_OF_KEYS, |
634 | )); |
635 | } |
636 | } |
637 | // NOTE: BTreeSet has an optimization inside of impl <T> FromIterator<T> for BTreeSet<T, Global>, |
638 | // based on BTreeMap::bulk_build_from_sorted_iter |
639 | Ok(vec.into_iter().collect::<BTreeSet<T>>()) |
640 | } |
641 | } |
642 | |
643 | impl<K, V> BorshDeserialize for BTreeMap<K, V> |
644 | where |
645 | K: BorshDeserialize + Ord, |
646 | V: BorshDeserialize, |
647 | { |
648 | #[inline ] |
649 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
650 | check_zst::<K>()?; |
651 | // NOTE: deserialize-as-you-go approach as once was in HashSet is better in the sense |
652 | // that it allows to fail early, and not allocate memory for all the entries |
653 | // which may fail `cmp()` checks |
654 | // NOTE: deserialize first to `Vec<(K, V)>` is faster |
655 | let vec = <Vec<(K, V)>>::deserialize_reader(reader)?; |
656 | |
657 | #[cfg (feature = "de_strict_order" )] |
658 | // TODO: replace with `is_sorted` api when stabilizes https://github.com/rust-lang/rust/issues/53485 |
659 | // TODO: first replace with `array_windows` api when stabilizes https://github.com/rust-lang/rust/issues/75027 |
660 | for pair in vec.windows(2) { |
661 | let [(a_k, _a_v), (b_k, _b_v)] = pair else { |
662 | unreachable!("`windows` always return a slice of length 2 or nothing" ); |
663 | }; |
664 | let cmp_result = a_k.cmp(b_k).is_lt(); |
665 | if !cmp_result { |
666 | return Err(Error::new( |
667 | ErrorKind::InvalidData, |
668 | ERROR_WRONG_ORDER_OF_KEYS, |
669 | )); |
670 | } |
671 | } |
672 | |
673 | // NOTE: BTreeMap has an optimization inside of impl<K, V> FromIterator<(K, V)> for BTreeMap<K, V, Global>, |
674 | // based on BTreeMap::bulk_build_from_sorted_iter |
675 | Ok(vec.into_iter().collect::<BTreeMap<K, V>>()) |
676 | } |
677 | } |
678 | |
679 | #[cfg (feature = "std" )] |
680 | impl BorshDeserialize for std::net::SocketAddr { |
681 | #[inline ] |
682 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
683 | let kind: u8 = u8::deserialize_reader(reader)?; |
684 | match kind { |
685 | 0 => std::net::SocketAddrV4::deserialize_reader(reader).map(op:std::net::SocketAddr::V4), |
686 | 1 => std::net::SocketAddrV6::deserialize_reader(reader).map(op:std::net::SocketAddr::V6), |
687 | value: u8 => Err(Error::new( |
688 | kind:ErrorKind::InvalidData, |
689 | error:format!("Invalid SocketAddr variant: {}" , value), |
690 | )), |
691 | } |
692 | } |
693 | } |
694 | |
695 | #[cfg (feature = "std" )] |
696 | impl BorshDeserialize for std::net::IpAddr { |
697 | #[inline ] |
698 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
699 | let kind: u8 = u8::deserialize_reader(reader)?; |
700 | match kind { |
701 | 0u8 => { |
702 | // Deserialize an Ipv4Addr and convert it to IpAddr::V4 |
703 | let ipv4_addr: Ipv4Addr = std::net::Ipv4Addr::deserialize_reader(reader)?; |
704 | Ok(std::net::IpAddr::V4(ipv4_addr)) |
705 | } |
706 | 1u8 => { |
707 | // Deserialize an Ipv6Addr and convert it to IpAddr::V6 |
708 | let ipv6_addr: Ipv6Addr = std::net::Ipv6Addr::deserialize_reader(reader)?; |
709 | Ok(std::net::IpAddr::V6(ipv6_addr)) |
710 | } |
711 | value: u8 => Err(Error::new( |
712 | kind:ErrorKind::InvalidData, |
713 | error:format!("Invalid IpAddr variant: {}" , value), |
714 | )), |
715 | } |
716 | } |
717 | } |
718 | |
719 | #[cfg (feature = "std" )] |
720 | impl BorshDeserialize for std::net::SocketAddrV4 { |
721 | #[inline ] |
722 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
723 | let ip: Ipv4Addr = std::net::Ipv4Addr::deserialize_reader(reader)?; |
724 | let port: u16 = u16::deserialize_reader(reader)?; |
725 | Ok(std::net::SocketAddrV4::new(ip, port)) |
726 | } |
727 | } |
728 | |
729 | #[cfg (feature = "std" )] |
730 | impl BorshDeserialize for std::net::SocketAddrV6 { |
731 | #[inline ] |
732 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
733 | let ip: Ipv6Addr = std::net::Ipv6Addr::deserialize_reader(reader)?; |
734 | let port: u16 = u16::deserialize_reader(reader)?; |
735 | Ok(std::net::SocketAddrV6::new(ip, port, flowinfo:0, scope_id:0)) |
736 | } |
737 | } |
738 | |
739 | #[cfg (feature = "std" )] |
740 | impl BorshDeserialize for std::net::Ipv4Addr { |
741 | #[inline ] |
742 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
743 | let mut buf: [u8; 4] = [0u8; 4]; |
744 | reader |
745 | .read_exact(&mut buf) |
746 | .map_err(op:unexpected_eof_to_unexpected_length_of_input)?; |
747 | Ok(std::net::Ipv4Addr::from(buf)) |
748 | } |
749 | } |
750 | |
751 | #[cfg (feature = "std" )] |
752 | impl BorshDeserialize for std::net::Ipv6Addr { |
753 | #[inline ] |
754 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
755 | let mut buf: [u8; 16] = [0u8; 16]; |
756 | reader |
757 | .read_exact(&mut buf) |
758 | .map_err(op:unexpected_eof_to_unexpected_length_of_input)?; |
759 | Ok(std::net::Ipv6Addr::from(buf)) |
760 | } |
761 | } |
762 | |
763 | impl<T, U> BorshDeserialize for Box<T> |
764 | where |
765 | U: Into<Box<T>> + Borrow<T>, |
766 | T: ToOwned<Owned = U> + ?Sized, |
767 | T::Owned: BorshDeserialize, |
768 | { |
769 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
770 | Ok(T::Owned::deserialize_reader(reader)?.into()) |
771 | } |
772 | } |
773 | |
774 | impl<T, const N: usize> BorshDeserialize for [T; N] |
775 | where |
776 | T: BorshDeserialize, |
777 | { |
778 | #[inline ] |
779 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
780 | struct ArrayDropGuard<T, const N: usize> { |
781 | buffer: [MaybeUninit<T>; N], |
782 | init_count: usize, |
783 | } |
784 | impl<T, const N: usize> Drop for ArrayDropGuard<T, N> { |
785 | fn drop(&mut self) { |
786 | let init_range = &mut self.buffer[..self.init_count]; |
787 | // SAFETY: Elements up to self.init_count have been initialized. Assumes this value |
788 | // is only incremented in `fill_buffer`, which writes the element before |
789 | // increasing the init_count. |
790 | unsafe { |
791 | core::ptr::drop_in_place(init_range as *mut _ as *mut [T]); |
792 | }; |
793 | } |
794 | } |
795 | impl<T, const N: usize> ArrayDropGuard<T, N> { |
796 | unsafe fn transmute_to_array(mut self) -> [T; N] { |
797 | debug_assert_eq!(self.init_count, N); |
798 | // Set init_count to 0 so that the values do not get dropped twice. |
799 | self.init_count = 0; |
800 | // SAFETY: This cast is required because `mem::transmute` does not work with |
801 | // const generics https://github.com/rust-lang/rust/issues/61956. This |
802 | // array is guaranteed to be initialized by this point. |
803 | core::ptr::read(&self.buffer as *const _ as *const [T; N]) |
804 | } |
805 | fn fill_buffer(&mut self, mut f: impl FnMut() -> Result<T>) -> Result<()> { |
806 | // TODO: replace with `core::array::try_from_fn` when stabilized to avoid manually |
807 | // dropping uninitialized values through the guard drop. |
808 | for elem in self.buffer.iter_mut() { |
809 | elem.write(f()?); |
810 | self.init_count += 1; |
811 | } |
812 | Ok(()) |
813 | } |
814 | } |
815 | |
816 | if let Some(arr) = T::array_from_reader(reader)? { |
817 | Ok(arr) |
818 | } else { |
819 | let mut result = ArrayDropGuard { |
820 | buffer: unsafe { MaybeUninit::uninit().assume_init() }, |
821 | init_count: 0, |
822 | }; |
823 | |
824 | result.fill_buffer(|| T::deserialize_reader(reader))?; |
825 | |
826 | // SAFETY: The elements up to `i` have been initialized in `fill_buffer`. |
827 | Ok(unsafe { result.transmute_to_array() }) |
828 | } |
829 | } |
830 | } |
831 | |
832 | #[test ] |
833 | fn array_deserialization_doesnt_leak() { |
834 | use core::sync::atomic::{AtomicUsize, Ordering}; |
835 | |
836 | static DESERIALIZE_COUNT: AtomicUsize = AtomicUsize::new(0); |
837 | static DROP_COUNT: AtomicUsize = AtomicUsize::new(0); |
838 | |
839 | #[allow (unused)] |
840 | struct MyType(u8); |
841 | impl BorshDeserialize for MyType { |
842 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
843 | let val = u8::deserialize_reader(reader)?; |
844 | let v = DESERIALIZE_COUNT.fetch_add(1, Ordering::SeqCst); |
845 | if v >= 7 { |
846 | panic!("panic in deserialize" ); |
847 | } |
848 | Ok(MyType(val)) |
849 | } |
850 | } |
851 | impl Drop for MyType { |
852 | fn drop(&mut self) { |
853 | DROP_COUNT.fetch_add(1, Ordering::SeqCst); |
854 | } |
855 | } |
856 | |
857 | assert!(<[MyType; 5] as BorshDeserialize>::deserialize(&mut &[0u8; 3][..]).is_err()); |
858 | assert_eq!(DESERIALIZE_COUNT.load(Ordering::SeqCst), 3); |
859 | assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 3); |
860 | |
861 | assert!(<[MyType; 2] as BorshDeserialize>::deserialize(&mut &[0u8; 2][..]).is_ok()); |
862 | assert_eq!(DESERIALIZE_COUNT.load(Ordering::SeqCst), 5); |
863 | assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 5); |
864 | |
865 | #[cfg (feature = "std" )] |
866 | { |
867 | // Test that during a panic in deserialize, the values are still dropped. |
868 | let result = std::panic::catch_unwind(|| { |
869 | <[MyType; 3] as BorshDeserialize>::deserialize(&mut &[0u8; 3][..]).unwrap(); |
870 | }); |
871 | assert!(result.is_err()); |
872 | assert_eq!(DESERIALIZE_COUNT.load(Ordering::SeqCst), 8); |
873 | assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 7); // 5 because 6 panicked and was not init |
874 | } |
875 | } |
876 | |
877 | macro_rules! impl_tuple { |
878 | (@unit $name:ty) => { |
879 | impl BorshDeserialize for $name { |
880 | #[inline] |
881 | fn deserialize_reader<R: Read>(_reader: &mut R) -> Result<Self> { |
882 | Ok(<$name>::default()) |
883 | } |
884 | } |
885 | }; |
886 | |
887 | ($($name:ident)+) => { |
888 | impl<$($name),+> BorshDeserialize for ($($name,)+) |
889 | where $($name: BorshDeserialize,)+ |
890 | { |
891 | #[inline] |
892 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
893 | |
894 | Ok(($($name::deserialize_reader(reader)?,)+)) |
895 | } |
896 | } |
897 | }; |
898 | } |
899 | |
900 | impl_tuple!(@unit ()); |
901 | impl_tuple!(@unit core::ops::RangeFull); |
902 | |
903 | impl_tuple!(T0); |
904 | impl_tuple!(T0 T1); |
905 | impl_tuple!(T0 T1 T2); |
906 | impl_tuple!(T0 T1 T2 T3); |
907 | impl_tuple!(T0 T1 T2 T3 T4); |
908 | impl_tuple!(T0 T1 T2 T3 T4 T5); |
909 | impl_tuple!(T0 T1 T2 T3 T4 T5 T6); |
910 | impl_tuple!(T0 T1 T2 T3 T4 T5 T6 T7); |
911 | impl_tuple!(T0 T1 T2 T3 T4 T5 T6 T7 T8); |
912 | impl_tuple!(T0 T1 T2 T3 T4 T5 T6 T7 T8 T9); |
913 | impl_tuple!(T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10); |
914 | impl_tuple!(T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11); |
915 | impl_tuple!(T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12); |
916 | impl_tuple!(T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13); |
917 | impl_tuple!(T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14); |
918 | impl_tuple!(T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15); |
919 | impl_tuple!(T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15 T16); |
920 | impl_tuple!(T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15 T16 T17); |
921 | impl_tuple!(T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15 T16 T17 T18); |
922 | impl_tuple!(T0 T1 T2 T3 T4 T5 T6 T7 T8 T9 T10 T11 T12 T13 T14 T15 T16 T17 T18 T19); |
923 | |
924 | macro_rules! impl_range { |
925 | ($type:ident, $make:expr, $($side:ident),*) => { |
926 | impl<T: BorshDeserialize> BorshDeserialize for core::ops::$type<T> { |
927 | #[inline] |
928 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
929 | let ($($side,)*) = <_>::deserialize_reader(reader)?; |
930 | Ok($make) |
931 | } |
932 | } |
933 | }; |
934 | } |
935 | |
936 | impl_range!(Range, start..end, start, end); |
937 | impl_range!(RangeInclusive, start..=end, start, end); |
938 | impl_range!(RangeFrom, start.., start); |
939 | impl_range!(RangeTo, ..end, end); |
940 | impl_range!(RangeToInclusive, ..=end, end); |
941 | |
942 | /// Module is available if borsh is built with `features = ["rc"]`. |
943 | #[cfg (feature = "rc" )] |
944 | pub mod rc { |
945 | //! |
946 | //! Module defines [BorshDeserialize] implementation for |
947 | //! [alloc::rc::Rc](std::rc::Rc) and [alloc::sync::Arc](std::sync::Arc). |
948 | use crate::__private::maybestd::{boxed::Box, rc::Rc, sync::Arc}; |
949 | use crate::io::{Read, Result}; |
950 | use crate::BorshDeserialize; |
951 | |
952 | /// This impl requires the [`"rc"`] Cargo feature of borsh. |
953 | /// |
954 | /// Deserializing a data structure containing `Rc` will not attempt to |
955 | /// deduplicate `Rc` references to the same data. Every deserialized `Rc` |
956 | /// will end up with a strong count of 1. |
957 | impl<T: ?Sized> BorshDeserialize for Rc<T> |
958 | where |
959 | Box<T>: BorshDeserialize, |
960 | { |
961 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
962 | Ok(Box::<T>::deserialize_reader(reader)?.into()) |
963 | } |
964 | } |
965 | |
966 | /// This impl requires the [`"rc"`] Cargo feature of borsh. |
967 | /// |
968 | /// Deserializing a data structure containing `Arc` will not attempt to |
969 | /// deduplicate `Arc` references to the same data. Every deserialized `Arc` |
970 | /// will end up with a strong count of 1. |
971 | impl<T: ?Sized> BorshDeserialize for Arc<T> |
972 | where |
973 | Box<T>: BorshDeserialize, |
974 | { |
975 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
976 | Ok(Box::<T>::deserialize_reader(reader)?.into()) |
977 | } |
978 | } |
979 | } |
980 | |
981 | impl<T: ?Sized> BorshDeserialize for PhantomData<T> { |
982 | fn deserialize_reader<R: Read>(_: &mut R) -> Result<Self> { |
983 | Ok(PhantomData) |
984 | } |
985 | } |
986 | |
987 | impl<T> BorshDeserialize for core::cell::Cell<T> |
988 | where |
989 | T: BorshDeserialize + Copy, |
990 | { |
991 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
992 | <T as BorshDeserialize>::deserialize_reader(reader).map(op:core::cell::Cell::new) |
993 | } |
994 | } |
995 | |
996 | impl<T> BorshDeserialize for core::cell::RefCell<T> |
997 | where |
998 | T: BorshDeserialize, |
999 | { |
1000 | fn deserialize_reader<R: Read>(reader: &mut R) -> Result<Self> { |
1001 | <T as BorshDeserialize>::deserialize_reader(reader).map(op:core::cell::RefCell::new) |
1002 | } |
1003 | } |
1004 | |
1005 | /// Deserializes an object from a slice of bytes. |
1006 | /// # Example |
1007 | /// ``` |
1008 | /// use borsh::{BorshDeserialize, BorshSerialize, from_slice, to_vec}; |
1009 | /// |
1010 | /// /// derive is only available if borsh is built with `features = ["derive"]` |
1011 | /// # #[cfg (feature = "derive" )] |
1012 | /// #[derive(BorshSerialize, BorshDeserialize, PartialEq, Debug)] |
1013 | /// struct MyStruct { |
1014 | /// a: u64, |
1015 | /// b: Vec<u8>, |
1016 | /// } |
1017 | /// |
1018 | /// # #[cfg (feature = "derive" )] |
1019 | /// let original = MyStruct { a: 10, b: vec![1, 2, 3] }; |
1020 | /// # #[cfg (feature = "derive" )] |
1021 | /// let encoded = to_vec(&original).unwrap(); |
1022 | /// # #[cfg (feature = "derive" )] |
1023 | /// let decoded = from_slice::<MyStruct>(&encoded).unwrap(); |
1024 | /// # #[cfg (feature = "derive" )] |
1025 | /// assert_eq!(original, decoded); |
1026 | /// ``` |
1027 | /// # Panics |
1028 | /// If the data is invalid, this function will panic. |
1029 | /// # Errors |
1030 | /// If the data is invalid, this function will return an error. |
1031 | /// # Note |
1032 | /// This function will return an error if the data is not fully read. |
1033 | pub fn from_slice<T: BorshDeserialize>(v: &[u8]) -> Result<T> { |
1034 | let mut v_mut: &[u8] = v; |
1035 | let object: T = T::deserialize(&mut v_mut)?; |
1036 | if !v_mut.is_empty() { |
1037 | return Err(Error::new( |
1038 | kind:ErrorKind::InvalidData, |
1039 | error:crate::de::ERROR_NOT_ALL_BYTES_READ, |
1040 | )); |
1041 | } |
1042 | Ok(object) |
1043 | } |
1044 | |
1045 | /// Deserializes an object from a reader. |
1046 | /// # Example |
1047 | /// ``` |
1048 | /// use borsh::{BorshDeserialize, BorshSerialize, from_reader, to_vec}; |
1049 | /// |
1050 | /// /// derive is only available if borsh is built with `features = ["derive"]` |
1051 | /// # #[cfg (feature = "derive" )] |
1052 | /// #[derive(BorshSerialize, BorshDeserialize, PartialEq, Debug)] |
1053 | /// struct MyStruct { |
1054 | /// a: u64, |
1055 | /// b: Vec<u8>, |
1056 | /// } |
1057 | /// |
1058 | /// # #[cfg (feature = "derive" )] |
1059 | /// let original = MyStruct { a: 10, b: vec![1, 2, 3] }; |
1060 | /// # #[cfg (feature = "derive" )] |
1061 | /// let encoded = to_vec(&original).unwrap(); |
1062 | /// # #[cfg (feature = "derive" )] |
1063 | /// let decoded = from_reader::<_, MyStruct>(&mut encoded.as_slice()).unwrap(); |
1064 | /// # #[cfg (feature = "derive" )] |
1065 | /// assert_eq!(original, decoded); |
1066 | /// ``` |
1067 | pub fn from_reader<R: Read, T: BorshDeserialize>(reader: &mut R) -> Result<T> { |
1068 | let result: T = T::deserialize_reader(reader)?; |
1069 | let mut buf: [u8; 1] = [0u8; 1]; |
1070 | match reader.read_exact(&mut buf) { |
1071 | Err(f: Error) if f.kind() == ErrorKind::UnexpectedEof => Ok(result), |
1072 | _ => Err(Error::new(kind:ErrorKind::InvalidData, ERROR_NOT_ALL_BYTES_READ)), |
1073 | } |
1074 | } |
1075 | |