1use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
2use std::io::{Cursor, Error, Read};
3use std::mem::{forget, size_of};
4
5mod hint;
6
7const ERROR_NOT_ALL_BYTES_READ: &str = "Not all bytes read";
8
9pub trait BorshDeserialize: Sized {
11 fn deserialize<R: Read>(reader: &mut R) -> Result<Self, Error>;
12
13 fn try_from_slice(v: &[u8]) -> Result<Self, Error> {
15 let mut c = Cursor::new(v);
16 let result = Self::deserialize(&mut c)?;
17 if c.position() != v.len() as u64 {
18 return Err(std::io::Error::new(
19 std::io::ErrorKind::InvalidData,
20 ERROR_NOT_ALL_BYTES_READ,
21 ));
22 }
23 Ok(result)
24 }
25}
26
27impl BorshDeserialize for () {
28 fn deserialize<R: Read>(_reader: &mut R) -> Result<Self, Error> {
29 Ok(())
30 }
31}
32
33impl BorshDeserialize for u8 {
34 #[inline]
35 fn deserialize<R: Read>(reader: &mut R) -> Result<Self, Error> {
36 let mut res = 0u8;
37 reader.read_exact(std::slice::from_mut(&mut res))?;
38 Ok(res)
39 }
40}
41
42macro_rules! impl_for_integer {
43 ($type: ident) => {
44 impl BorshDeserialize for $type {
45 #[inline]
46 fn deserialize<R: Read>(reader: &mut R) -> Result<Self, Error> {
47 let mut data = [0u8; size_of::<$type>()];
48 reader.read_exact(&mut data)?;
49 Ok($type::from_le_bytes(data))
50 }
51 }
52 };
53}
54
55impl_for_integer!(i8);
56impl_for_integer!(i16);
57impl_for_integer!(i32);
58impl_for_integer!(i64);
59impl_for_integer!(i128);
60impl_for_integer!(u16);
61impl_for_integer!(u32);
62impl_for_integer!(u64);
63impl_for_integer!(u128);
64
65macro_rules! impl_for_float {
68 ($type: ident, $int_type: ident) => {
69 impl BorshDeserialize for $type {
70 fn deserialize<R: Read>(reader: &mut R) -> Result<Self, Error> {
71 let mut data = [0u8; size_of::<$type>()];
72 reader.read_exact(&mut data)?;
73 let res = $type::from_bits($int_type::from_le_bytes(data));
74 if res.is_nan() {
75 return Err(std::io::Error::new(
76 std::io::ErrorKind::InvalidInput,
77 "For portability reasons we do not allow to deserialize NaNs.",
78 ));
79 }
80 Ok(res)
81 }
82 }
83 };
84}
85
86impl_for_float!(f32, u32);
87impl_for_float!(f64, u64);
88
89impl BorshDeserialize for bool {
90 #[inline]
91 fn deserialize<R: Read>(reader: &mut R) -> Result<Self, Error> {
92 let mut buf = [0u8];
93 reader.read_exact(&mut buf)?;
94 Ok(buf[0] == 1)
95 }
96}
97
98impl<T> BorshDeserialize for Option<T>
99where
100 T: BorshDeserialize,
101{
102 #[inline]
103 fn deserialize<R: Read>(reader: &mut R) -> Result<Self, Error> {
104 let mut flag = [0u8];
105 reader.read_exact(&mut flag)?;
106 if flag[0] == 0 {
107 Ok(None)
108 } else {
109 Ok(Some(T::deserialize(reader)?))
110 }
111 }
112}
113
114impl<T, E> BorshDeserialize for Result<T, E>
115where
116 T: BorshDeserialize,
117 E: BorshDeserialize,
118{
119 #[inline]
120 fn deserialize<R: Read>(reader: &mut R) -> Result<Self, Error> {
121 let mut flag = [0u8];
122 reader.read_exact(&mut flag)?;
123 Ok(if flag[0] == 0 {
124 Ok(T::deserialize(reader)?)
125 } else {
126 Err(E::deserialize(reader)?)
127 })
128 }
129}
130
131impl BorshDeserialize for String {
132 #[inline]
133 fn deserialize<R: Read>(reader: &mut R) -> Result<Self, Error> {
134 let len = u32::deserialize(reader)?;
135 let mut result = Vec::with_capacity(hint::cautious::<u8>(len));
137 for _ in 0..len {
138 result.push(u8::deserialize(reader)?);
139 }
140 String::from_utf8(result)
141 .map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidData, err.to_string()))
142 }
143}
144
145#[cfg(feature = "std")]
146impl<T> BorshDeserialize for Vec<T>
147where
148 T: BorshDeserialize,
149{
150 #[inline]
151 fn deserialize<R: Read>(reader: &mut R) -> Result<Self, Error> {
152 let len = u32::deserialize(reader)?;
153 if size_of::<T>() == 0 {
154 let mut result = Vec::new();
155 result.push(T::deserialize(reader)?);
156
157 let p = result.as_mut_ptr();
158 unsafe {
159 forget(result);
160 let len = len as usize;
161 let result = Vec::from_raw_parts(p, len, len);
162 Ok(result)
163 }
164 } else {
165 let mut result = Vec::with_capacity(hint::cautious::<T>(len));
167 for _ in 0..len {
168 result.push(T::deserialize(reader)?);
169 }
170 Ok(result)
171 }
172 }
173}
174
175#[cfg(feature = "std")]
176impl<T, S> BorshDeserialize for HashSet<T, S>
177where
178 T: BorshDeserialize + Eq + std::hash::Hash,
179 S: std::hash::BuildHasher + Default,
180{
181 #[inline]
182 fn deserialize<R: Read>(reader: &mut R) -> Result<Self, Error> {
183 let vec = <Vec<T>>::deserialize(reader)?;
184 Ok(vec.into_iter().collect())
185 }
186}
187
188#[cfg(feature = "std")]
189impl<K, V, S> BorshDeserialize for HashMap<K, V, S>
190where
191 K: BorshDeserialize + Eq + std::hash::Hash,
192 V: BorshDeserialize,
193 S: std::hash::BuildHasher + Default,
194{
195 #[inline]
196 fn deserialize<R: Read>(reader: &mut R) -> Result<Self, Error> {
197 let len = u32::deserialize(reader)?;
198 let mut result = HashMap::default();
200 for _ in 0..len {
201 let key = K::deserialize(reader)?;
202 let value = V::deserialize(reader)?;
203 result.insert(key, value);
204 }
205 Ok(result)
206 }
207}
208
209#[cfg(feature = "std")]
210impl<T> BorshDeserialize for BTreeSet<T>
211where
212 T: BorshDeserialize + Ord,
213{
214 #[inline]
215 fn deserialize<R: Read>(reader: &mut R) -> Result<Self, Error> {
216 let vec = <Vec<T>>::deserialize(reader)?;
217 Ok(vec.into_iter().collect())
218 }
219}
220
221#[cfg(feature = "std")]
222impl<K, V> BorshDeserialize for BTreeMap<K, V>
223where
224 K: BorshDeserialize + Ord,
225 V: BorshDeserialize,
226{
227 #[inline]
228 fn deserialize<R: Read>(reader: &mut R) -> Result<Self, Error> {
229 let len = u32::deserialize(reader)?;
230 let mut result = BTreeMap::new();
231 for _ in 0..len {
232 let key = K::deserialize(reader)?;
233 let value = V::deserialize(reader)?;
234 result.insert(key, value);
235 }
236 Ok(result)
237 }
238}
239
240#[cfg(feature = "std")]
241impl BorshDeserialize for std::net::SocketAddr {
242 #[inline]
243 fn deserialize<R: Read>(reader: &mut R) -> Result<Self, Error> {
244 let kind = u8::deserialize(reader)?;
245 match kind {
246 0 => std::net::SocketAddrV4::deserialize(reader).map(std::net::SocketAddr::V4),
247 1 => std::net::SocketAddrV6::deserialize(reader).map(std::net::SocketAddr::V6),
248 value => Err(std::io::Error::new(
249 std::io::ErrorKind::InvalidInput,
250 format!("Invalid SocketAddr variant: {}", value),
251 )),
252 }
253 }
254}
255
256#[cfg(feature = "std")]
257impl BorshDeserialize for std::net::SocketAddrV4 {
258 #[inline]
259 fn deserialize<R: Read>(reader: &mut R) -> Result<Self, Error> {
260 let ip = std::net::Ipv4Addr::deserialize(reader)?;
261 let port = u16::deserialize(reader)?;
262 Ok(std::net::SocketAddrV4::new(ip, port))
263 }
264}
265
266#[cfg(feature = "std")]
267impl BorshDeserialize for std::net::SocketAddrV6 {
268 #[inline]
269 fn deserialize<R: Read>(reader: &mut R) -> Result<Self, Error> {
270 let ip = std::net::Ipv6Addr::deserialize(reader)?;
271 let port = u16::deserialize(reader)?;
272 Ok(std::net::SocketAddrV6::new(ip, port, 0, 0))
273 }
274}
275
276#[cfg(feature = "std")]
277impl BorshDeserialize for std::net::Ipv4Addr {
278 #[inline]
279 fn deserialize<R: Read>(reader: &mut R) -> Result<Self, Error> {
280 let mut buf = [0u8; 4];
281 reader.read_exact(&mut buf)?;
282 Ok(std::net::Ipv4Addr::from(buf))
283 }
284}
285
286#[cfg(feature = "std")]
287impl BorshDeserialize for std::net::Ipv6Addr {
288 #[inline]
289 fn deserialize<R: Read>(reader: &mut R) -> Result<Self, Error> {
290 let mut buf = [0u8; 16];
291 reader.read_exact(&mut buf)?;
292 Ok(std::net::Ipv6Addr::from(buf))
293 }
294}
295
296impl BorshDeserialize for Box<[u8]> {
297 fn deserialize<R: Read>(reader: &mut R) -> Result<Self, Error> {
298 let len = u32::deserialize(reader)?;
299 let mut result = Vec::with_capacity(hint::cautious::<u8>(len));
301 for _ in 0..len {
302 result.push(u8::deserialize(reader)?);
303 }
304 Ok(result.into_boxed_slice())
305 }
306}
307
308macro_rules! impl_arrays {
309 ($($len:expr => ($($n:expr)+))+) => {
310 $(
311 impl<T: BorshDeserialize> BorshDeserialize for [T; $len] {
312 #[inline]
313 fn deserialize<R: Read>(reader: &mut R) -> Result<Self, Error> {
314 Ok([$(
317 T::deserialize(reader)
318 .map_err(|e|
319 Error::new(
320 std::io::ErrorKind::InvalidData,
321 format!("error deserializing element at index {}: {}", $n, e)
322 )
323 )?
324 ),+])
325 }
326 }
327 )+
328 };
329}
330
331impl<T: BorshDeserialize> BorshDeserialize for [T; 0] {
332 fn deserialize<R: Read>(_reader: &mut R) -> Result<Self, Error> {
333 Ok([])
334 }
335}
336
337oasis_borsh_derive::_gen_seq_macro! {
338 impl_arrays => (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 32 64 65)
339}
340
341macro_rules! impl_tuples {
342 ($($len:literal => ($($name:ident)+))+) => {
343 $(
344 impl<$($name: BorshDeserialize),+> BorshDeserialize for ($($name),+) {
345 fn deserialize<R: Read>(reader: &mut R) -> Result<Self, Error> {
346 Ok(($($name::deserialize(reader)?,)+))
347 }
348 }
349 )*
350 }
351}
352
353oasis_borsh_derive::_gen_seq_macro! {
354 impl_tuples => T :: (2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19)
355}