1use core::convert::TryFrom;
2use core::mem::size_of;
3
4use crate::maybestd::{
5 borrow::{Cow, ToOwned},
6 boxed::Box,
7 collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque},
8 io::{ErrorKind, Result, Write},
9 string::String,
10 vec::Vec,
11};
12
13const DEFAULT_SERIALIZER_CAPACITY: usize = 1024;
14
15pub trait BorshSerialize {
17 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()>;
18
19 fn try_to_vec(&self) -> Result<Vec<u8>> {
21 let mut result = Vec::with_capacity(DEFAULT_SERIALIZER_CAPACITY);
22 self.serialize(&mut result)?;
23 Ok(result)
24 }
25
26 #[inline]
32 fn is_u8() -> bool {
33 false
34 }
35}
36
37impl BorshSerialize for u8 {
38 #[inline]
39 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
40 writer.write_all(core::slice::from_ref(self))
41 }
42
43 #[inline]
44 fn is_u8() -> bool {
45 true
46 }
47}
48
49macro_rules! impl_for_integer {
50 ($type: ident) => {
51 impl BorshSerialize for $type {
52 #[inline]
53 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
54 let bytes = self.to_le_bytes();
55 writer.write_all(&bytes)
56 }
57 }
58 };
59}
60
61impl_for_integer!(i8);
62impl_for_integer!(i16);
63impl_for_integer!(i32);
64impl_for_integer!(i64);
65impl_for_integer!(i128);
66impl_for_integer!(u16);
67impl_for_integer!(u32);
68impl_for_integer!(u64);
69impl_for_integer!(u128);
70
71macro_rules! impl_for_float {
74 ($type: ident) => {
75 impl BorshSerialize for $type {
76 #[inline]
77 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
78 assert!(
79 !self.is_nan(),
80 "For portability reasons we do not allow to serialize NaNs."
81 );
82 writer.write_all(&self.to_bits().to_le_bytes())
83 }
84 }
85 };
86}
87
88impl_for_float!(f32);
89impl_for_float!(f64);
90
91impl BorshSerialize for bool {
92 #[inline]
93 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
94 (if *self { 1u8 } else { 0u8 }).serialize(writer)
95 }
96}
97
98impl<T> BorshSerialize for Option<T>
99where
100 T: BorshSerialize,
101{
102 #[inline]
103 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
104 match self {
105 None => 0u8.serialize(writer),
106 Some(value) => {
107 1u8.serialize(writer)?;
108 value.serialize(writer)
109 }
110 }
111 }
112}
113
114impl<T, E> BorshSerialize for core::result::Result<T, E>
115where
116 T: BorshSerialize,
117 E: BorshSerialize,
118{
119 #[inline]
120 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
121 match self {
122 Err(e) => {
123 0u8.serialize(writer)?;
124 e.serialize(writer)
125 }
126 Ok(v) => {
127 1u8.serialize(writer)?;
128 v.serialize(writer)
129 }
130 }
131 }
132}
133
134impl BorshSerialize for str {
135 #[inline]
136 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
137 self.as_bytes().serialize(writer)
138 }
139}
140
141impl BorshSerialize for String {
142 #[inline]
143 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
144 self.as_bytes().serialize(writer)
145 }
146}
147
148#[inline]
150fn serialize_slice<T: BorshSerialize, W: Write>(data: &[T], writer: &mut W) -> Result<()> {
151 if T::is_u8() && size_of::<T>() == size_of::<u8>() {
152 let buf = unsafe { core::slice::from_raw_parts(data.as_ptr() as *const u8, data.len()) };
157 writer.write_all(buf)?;
158 } else {
159 for item in data {
160 item.serialize(writer)?;
161 }
162 }
163 Ok(())
164}
165
166impl<T> BorshSerialize for [T]
167where
168 T: BorshSerialize,
169{
170 #[inline]
171 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
172 writer.write_all(
173 &(u32::try_from(self.len()).map_err(|_| ErrorKind::InvalidInput)?).to_le_bytes(),
174 )?;
175 serialize_slice(self, writer)
176 }
177}
178
179impl<T: BorshSerialize + ?Sized> BorshSerialize for &T {
180 #[inline]
181 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
182 (*self).serialize(writer)
183 }
184}
185
186impl<T> BorshSerialize for Cow<'_, T>
187where
188 T: BorshSerialize + ToOwned + ?Sized,
189{
190 #[inline]
191 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
192 self.as_ref().serialize(writer)
193 }
194}
195
196impl<T> BorshSerialize for Vec<T>
197where
198 T: BorshSerialize,
199{
200 #[inline]
201 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
202 self.as_slice().serialize(writer)
203 }
204}
205
206impl<T> BorshSerialize for VecDeque<T>
207where
208 T: BorshSerialize,
209{
210 #[inline]
211 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
212 writer.write_all(
213 &(u32::try_from(self.len()).map_err(|_| ErrorKind::InvalidInput)?).to_le_bytes(),
214 )?;
215 let slices = self.as_slices();
216 serialize_slice(slices.0, writer)?;
217 serialize_slice(slices.1, writer)
218 }
219}
220
221impl<T> BorshSerialize for LinkedList<T>
222where
223 T: BorshSerialize,
224{
225 #[inline]
226 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
227 writer.write_all(
228 &(u32::try_from(self.len()).map_err(|_| ErrorKind::InvalidInput)?).to_le_bytes(),
229 )?;
230 for item in self {
231 item.serialize(writer)?;
232 }
233 Ok(())
234 }
235}
236
237impl<T> BorshSerialize for BinaryHeap<T>
238where
239 T: BorshSerialize,
240{
241 #[inline]
242 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
243 writer.write_all(
247 &(u32::try_from(self.len()).map_err(|_| ErrorKind::InvalidInput)?).to_le_bytes(),
248 )?;
249 for item in self {
250 item.serialize(writer)?;
251 }
252 Ok(())
253 }
254}
255
256impl<K, V> BorshSerialize for HashMap<K, V>
257where
258 K: BorshSerialize + PartialOrd,
259 V: BorshSerialize,
260{
261 #[inline]
262 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
263 let mut vec = self.iter().collect::<Vec<_>>();
264 vec.sort_by(|(a, _), (b, _)| a.partial_cmp(b).unwrap());
265 u32::try_from(vec.len())
266 .map_err(|_| ErrorKind::InvalidInput)?
267 .serialize(writer)?;
268 for (key, value) in vec {
269 key.serialize(writer)?;
270 value.serialize(writer)?;
271 }
272 Ok(())
273 }
274}
275
276impl<T> BorshSerialize for HashSet<T>
277where
278 T: BorshSerialize + PartialOrd,
279{
280 #[inline]
281 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
282 let mut vec = self.iter().collect::<Vec<_>>();
283 vec.sort_by(|a, b| a.partial_cmp(b).unwrap());
284 u32::try_from(vec.len())
285 .map_err(|_| ErrorKind::InvalidInput)?
286 .serialize(writer)?;
287 for item in vec {
288 item.serialize(writer)?;
289 }
290 Ok(())
291 }
292}
293
294impl<K, V> BorshSerialize for BTreeMap<K, V>
295where
296 K: BorshSerialize,
297 V: BorshSerialize,
298{
299 #[inline]
300 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
301 u32::try_from(self.len())
305 .map_err(|_| ErrorKind::InvalidInput)?
306 .serialize(writer)?;
307 for (key, value) in self {
308 key.serialize(writer)?;
309 value.serialize(writer)?;
310 }
311 Ok(())
312 }
313}
314
315impl<T> BorshSerialize for BTreeSet<T>
316where
317 T: BorshSerialize,
318{
319 #[inline]
320 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
321 u32::try_from(self.len())
324 .map_err(|_| ErrorKind::InvalidInput)?
325 .serialize(writer)?;
326 for item in self {
327 item.serialize(writer)?;
328 }
329 Ok(())
330 }
331}
332
333#[cfg(feature = "std")]
334impl BorshSerialize for std::net::SocketAddr {
335 #[inline]
336 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
337 match *self {
338 std::net::SocketAddr::V4(ref addr) => {
339 0u8.serialize(writer)?;
340 addr.serialize(writer)
341 }
342 std::net::SocketAddr::V6(ref addr) => {
343 1u8.serialize(writer)?;
344 addr.serialize(writer)
345 }
346 }
347 }
348}
349
350#[cfg(feature = "std")]
351impl BorshSerialize for std::net::SocketAddrV4 {
352 #[inline]
353 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
354 self.ip().serialize(writer)?;
355 self.port().serialize(writer)
356 }
357}
358
359#[cfg(feature = "std")]
360impl BorshSerialize for std::net::SocketAddrV6 {
361 #[inline]
362 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
363 self.ip().serialize(writer)?;
364 self.port().serialize(writer)
365 }
366}
367
368#[cfg(feature = "std")]
369impl BorshSerialize for std::net::Ipv4Addr {
370 #[inline]
371 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
372 writer.write_all(&self.octets())
373 }
374}
375
376#[cfg(feature = "std")]
377impl BorshSerialize for std::net::Ipv6Addr {
378 #[inline]
379 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
380 writer.write_all(&self.octets())
381 }
382}
383
384impl<T: BorshSerialize + ?Sized> BorshSerialize for Box<T> {
385 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
386 self.as_ref().serialize(writer)
387 }
388}
389
390macro_rules! impl_arrays {
391 ($($len:expr)+) => {
392 $(
393 impl<T> BorshSerialize for [T; $len]
394 where T: BorshSerialize
395 {
396 #[inline]
397 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
398 if T::is_u8() && size_of::<T>() == size_of::<u8>() {
399 let buf = unsafe { core::slice::from_raw_parts(self.as_ptr() as *const u8, self.len()) };
404 writer.write_all(buf)?;
405 } else {
406 for el in self.iter() {
407 el.serialize(writer)?;
408 }
409 }
410 Ok(())
411 }
412 }
413 )+
414 };
415}
416
417impl<T> BorshSerialize for [T; 0]
418where
419 T: BorshSerialize,
420{
421 #[inline]
422 fn serialize<W: Write>(&self, _writer: &mut W) -> Result<()> {
423 Ok(())
424 }
425}
426
427impl_arrays!(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 64 65 128 256 512 1024 2048);
428
429impl BorshSerialize for () {
430 fn serialize<W: Write>(&self, _writer: &mut W) -> Result<()> {
431 Ok(())
432 }
433}
434
435macro_rules! impl_tuple {
436 ($($idx:tt $name:ident)+) => {
437 impl<$($name),+> BorshSerialize for ($($name),+)
438 where $($name: BorshSerialize,)+
439 {
440 #[inline]
441 fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
442 $(self.$idx.serialize(writer)?;)+
443 Ok(())
444 }
445 }
446 };
447}
448
449impl_tuple!(0 T0 1 T1);
450impl_tuple!(0 T0 1 T1 2 T2);
451impl_tuple!(0 T0 1 T1 2 T2 3 T3);
452impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4);
453impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5);
454impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6);
455impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7);
456impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8);
457impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9);
458impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10);
459impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11);
460impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12);
461impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13);
462impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14);
463impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15);
464impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15 16 T16);
465impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15 16 T16 17 T17);
466impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15 16 T16 17 T17 18 T18);
467impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15 16 T16 17 T17 18 T18 19 T19);