|
1 | 1 | {% extends "layout.njk" %} |
2 | 2 | {% block main %} |
3 | 3 |
|
4 | | -use std::fmt::Debug; |
5 | | -use std::io::Write; |
6 | | -use std::ops::{Deref, DerefMut}; |
7 | | - |
8 | | -use borsh::maybestd::io::Read; |
9 | | -use borsh::{BorshDeserialize, BorshSerialize}; |
10 | | - |
11 | | -/// A vector that deserializes from a stream of bytes. |
12 | | -/// |
13 | | -/// This is useful for deserializing a vector that does not have |
14 | | -/// a length prefix. In order to determine how many elements to deserialize, |
15 | | -/// the type of the elements must implement the trait `Sized`. |
16 | | -pub struct RemainderVec<T: BorshSerialize + BorshDeserialize>(Vec<T>); |
17 | | - |
18 | | -/// Deferences the inner `Vec` type. |
19 | | -impl<T> Deref for RemainderVec<T> |
20 | | -where |
21 | | - T: BorshSerialize + BorshDeserialize, |
22 | | -{ |
23 | | - type Target = Vec<T>; |
24 | | - |
25 | | - fn deref(&self) -> &Self::Target { |
26 | | - &self.0 |
27 | | - } |
28 | | -} |
29 | | - |
30 | | -/// Deferences the inner `Vec` type as mutable. |
31 | | -impl<T> DerefMut for RemainderVec<T> |
32 | | -where |
33 | | - T: BorshSerialize + BorshDeserialize, |
34 | | -{ |
35 | | - fn deref_mut(&mut self) -> &mut Self::Target { |
36 | | - &mut self.0 |
37 | | - } |
38 | | -} |
39 | | - |
40 | | -/// `Debug` implementation for `RemainderVec`. |
41 | | -/// |
42 | | -/// This implementation simply forwards to the inner `Vec` type. |
43 | | -impl<T> Debug for RemainderVec<T> |
44 | | -where |
45 | | - T: BorshSerialize + BorshDeserialize + Debug, |
46 | | -{ |
47 | | - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
48 | | - f.write_fmt(format_args!("{:?}", self.0)) |
49 | | - } |
50 | | -} |
51 | | - |
52 | | -impl<T> BorshDeserialize for RemainderVec<T> |
53 | | -where |
54 | | - T: BorshSerialize + BorshDeserialize, |
55 | | -{ |
56 | | - fn deserialize_reader<R: Read>(reader: &mut R) -> borsh::maybestd::io::Result<Self> { |
57 | | - let length = std::mem::size_of::<T>(); |
58 | | - // buffer to read the data |
59 | | - let mut buffer = vec![0u8; length]; |
60 | | - // vec to store the items |
61 | | - let mut items: Vec<T> = Vec::new(); |
62 | | - |
63 | | - loop { |
64 | | - match reader.read(&mut buffer)? { |
65 | | - 0 => break, |
66 | | - n if n == length => items.push(T::deserialize(&mut buffer.as_slice())?), |
67 | | - e => { |
68 | | - return Err(borsh::maybestd::io::Error::new( |
69 | | - borsh::maybestd::io::ErrorKind::InvalidData, |
70 | | - format!("unexpected number of bytes (read {e}, expected {length})"), |
71 | | - )) |
72 | | - } |
73 | | - } |
74 | | - } |
75 | | - |
76 | | - Ok(Self(items)) |
77 | | - } |
78 | | -} |
79 | | - |
80 | | -impl<T> BorshSerialize for RemainderVec<T> |
81 | | -where |
82 | | - T: BorshSerialize + BorshDeserialize, |
83 | | -{ |
84 | | - fn serialize<W: Write>(&self, writer: &mut W) -> borsh::maybestd::io::Result<()> { |
85 | | - // serialize each item without adding a prefix for the length |
86 | | - for item in self.0.iter() { |
87 | | - item.serialize(writer)?; |
88 | | - } |
89 | | - |
90 | | - Ok(()) |
91 | | - } |
92 | | -} |
93 | | - |
94 | 4 | {# |
95 | 5 | The following types are used as responses for function that fetch accounts. |
96 | 6 | Ideally, these types live in a shared crate that can be used by the client but |
|
0 commit comments