borsh/ser/
mod.rs

1use core::convert::TryFrom;
2use core::marker::PhantomData;
3
4use crate::__private::maybestd::{
5    borrow::{Cow, ToOwned},
6    boxed::Box,
7    collections::{BTreeMap, BTreeSet, LinkedList, VecDeque},
8    string::String,
9    vec::Vec,
10};
11use crate::error::check_zst;
12use crate::io::{Error, ErrorKind, Result, Write};
13
14pub(crate) mod helpers;
15
16const FLOAT_NAN_ERR: &str = "For portability reasons we do not allow to serialize NaNs.";
17
18/// A data-structure that can be serialized into binary format by NBOR.
19///
20/// ```
21/// use borsh::BorshSerialize;
22///
23/// /// derive is only available if borsh is built with `features = ["derive"]`
24/// # #[cfg(feature = "derive")]
25/// #[derive(BorshSerialize)]
26/// struct MyBorshSerializableStruct {
27///     value: String,
28/// }
29///
30///
31/// # #[cfg(feature = "derive")]
32/// let x = MyBorshSerializableStruct { value: "hello".to_owned() };
33/// let mut buffer: Vec<u8> = Vec::new();
34/// # #[cfg(feature = "derive")]
35/// x.serialize(&mut buffer).unwrap();
36/// # #[cfg(feature = "derive")]
37/// let single_serialized_buffer_len = buffer.len();
38///
39/// # #[cfg(feature = "derive")]
40/// x.serialize(&mut buffer).unwrap();
41/// # #[cfg(feature = "derive")]
42/// assert_eq!(buffer.len(), single_serialized_buffer_len * 2);
43///
44/// # #[cfg(feature = "derive")]
45/// let mut buffer: Vec<u8> = vec![0; 1024 + single_serialized_buffer_len];
46/// # #[cfg(feature = "derive")]
47/// let mut buffer_slice_enough_for_the_data = &mut buffer[1024..1024 + single_serialized_buffer_len];
48/// # #[cfg(feature = "derive")]
49/// x.serialize(&mut buffer_slice_enough_for_the_data).unwrap();
50/// ```
51pub trait BorshSerialize {
52    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()>;
53
54    #[inline]
55    #[doc(hidden)]
56    fn u8_slice(slice: &[Self]) -> Option<&[u8]>
57    where
58        Self: Sized,
59    {
60        let _ = slice;
61        None
62    }
63}
64
65impl BorshSerialize for u8 {
66    #[inline]
67    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
68        writer.write_all(core::slice::from_ref(self))
69    }
70
71    #[inline]
72    fn u8_slice(slice: &[Self]) -> Option<&[u8]> {
73        Some(slice)
74    }
75}
76
77macro_rules! impl_for_integer {
78    ($type: ident) => {
79        impl BorshSerialize for $type {
80            #[inline]
81            fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
82                let bytes = self.to_le_bytes();
83                writer.write_all(&bytes)
84            }
85        }
86    };
87}
88
89impl_for_integer!(i8);
90impl_for_integer!(i16);
91impl_for_integer!(i32);
92impl_for_integer!(i64);
93impl_for_integer!(i128);
94impl_for_integer!(u16);
95impl_for_integer!(u32);
96impl_for_integer!(u64);
97impl_for_integer!(u128);
98
99macro_rules! impl_for_nonzero_integer {
100    ($type: ty) => {
101        impl BorshSerialize for $type {
102            #[inline]
103            fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
104                BorshSerialize::serialize(&self.get(), writer)
105            }
106        }
107    };
108}
109
110impl_for_nonzero_integer!(core::num::NonZeroI8);
111impl_for_nonzero_integer!(core::num::NonZeroI16);
112impl_for_nonzero_integer!(core::num::NonZeroI32);
113impl_for_nonzero_integer!(core::num::NonZeroI64);
114impl_for_nonzero_integer!(core::num::NonZeroI128);
115impl_for_nonzero_integer!(core::num::NonZeroU8);
116impl_for_nonzero_integer!(core::num::NonZeroU16);
117impl_for_nonzero_integer!(core::num::NonZeroU32);
118impl_for_nonzero_integer!(core::num::NonZeroU64);
119impl_for_nonzero_integer!(core::num::NonZeroU128);
120impl_for_nonzero_integer!(core::num::NonZeroUsize);
121
122impl BorshSerialize for isize {
123    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
124        BorshSerialize::serialize(&(*self as i64), writer)
125    }
126}
127
128impl BorshSerialize for usize {
129    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
130        BorshSerialize::serialize(&(*self as u64), writer)
131    }
132}
133
134// Note NaNs have a portability issue. Specifically, signalling NaNs on MIPS are quiet NaNs on x86,
135// and vice-versa. We disallow NaNs to avoid this issue.
136macro_rules! impl_for_float {
137    ($type: ident) => {
138        impl BorshSerialize for $type {
139            #[inline]
140            fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
141                if self.is_nan() {
142                    return Err(Error::new(ErrorKind::InvalidData, FLOAT_NAN_ERR));
143                }
144                writer.write_all(&self.to_bits().to_le_bytes())
145            }
146        }
147    };
148}
149
150impl_for_float!(f32);
151impl_for_float!(f64);
152
153impl BorshSerialize for bool {
154    #[inline]
155    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
156        (u8::from(*self)).serialize(writer)
157    }
158}
159
160impl<T> BorshSerialize for Option<T>
161where
162    T: BorshSerialize,
163{
164    #[inline]
165    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
166        match self {
167            None => 0u8.serialize(writer),
168            Some(value) => {
169                1u8.serialize(writer)?;
170                value.serialize(writer)
171            }
172        }
173    }
174}
175
176impl<T, E> BorshSerialize for core::result::Result<T, E>
177where
178    T: BorshSerialize,
179    E: BorshSerialize,
180{
181    #[inline]
182    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
183        match self {
184            Err(e) => {
185                0u8.serialize(writer)?;
186                e.serialize(writer)
187            }
188            Ok(v) => {
189                1u8.serialize(writer)?;
190                v.serialize(writer)
191            }
192        }
193    }
194}
195
196impl BorshSerialize for str {
197    #[inline]
198    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
199        self.as_bytes().serialize(writer)
200    }
201}
202
203impl BorshSerialize for String {
204    #[inline]
205    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
206        self.as_bytes().serialize(writer)
207    }
208}
209
210/// Module is available if borsh is built with `features = ["ascii"]`.
211#[cfg(feature = "ascii")]
212pub mod ascii {
213    //!
214    //! Module defines [BorshSerialize] implementation for
215    //! some types from [ascii](::ascii) crate.
216    use super::BorshSerialize;
217    use crate::io::{Result, Write};
218
219    impl BorshSerialize for ascii::AsciiChar {
220        #[inline]
221        fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
222            self.as_byte().serialize(writer)
223        }
224    }
225
226    impl BorshSerialize for ascii::AsciiStr {
227        #[inline]
228        fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
229            self.as_bytes().serialize(writer)
230        }
231    }
232
233    impl BorshSerialize for ascii::AsciiString {
234        #[inline]
235        fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
236            self.as_bytes().serialize(writer)
237        }
238    }
239}
240
241/// Helper method that is used to serialize a slice of data (without the length marker).
242#[inline]
243fn serialize_slice<T: BorshSerialize, W: Write>(data: &[T], writer: &mut W) -> Result<()> {
244    if let Some(u8_slice) = T::u8_slice(data) {
245        writer.write_all(u8_slice)?;
246    } else {
247        for item in data {
248            item.serialize(writer)?;
249        }
250    }
251    Ok(())
252}
253
254impl<T> BorshSerialize for [T]
255where
256    T: BorshSerialize,
257{
258    #[inline]
259    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
260        writer.write_all(
261            &(u32::try_from(self.len()).map_err(|_| ErrorKind::InvalidData)?).to_le_bytes(),
262        )?;
263        serialize_slice(self, writer)
264    }
265}
266
267impl<T: BorshSerialize + ?Sized> BorshSerialize for &T {
268    #[inline]
269    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
270        (*self).serialize(writer)
271    }
272}
273
274impl<T> BorshSerialize for Cow<'_, T>
275where
276    T: BorshSerialize + ToOwned + ?Sized,
277{
278    #[inline]
279    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
280        self.as_ref().serialize(writer)
281    }
282}
283
284impl<T> BorshSerialize for Vec<T>
285where
286    T: BorshSerialize,
287{
288    #[inline]
289    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
290        check_zst::<T>()?;
291
292        self.as_slice().serialize(writer)
293    }
294}
295
296#[cfg(feature = "bytes")]
297impl BorshSerialize for bytes::Bytes {
298    #[inline]
299    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
300        self.as_ref().serialize(writer)
301    }
302}
303
304#[cfg(feature = "bytes")]
305impl BorshSerialize for bytes::BytesMut {
306    #[inline]
307    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
308        self.as_ref().serialize(writer)
309    }
310}
311
312#[cfg(feature = "bson")]
313impl BorshSerialize for bson::oid::ObjectId {
314    #[inline]
315    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
316        self.bytes().serialize(writer)
317    }
318}
319
320impl<T> BorshSerialize for VecDeque<T>
321where
322    T: BorshSerialize,
323{
324    #[inline]
325    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
326        check_zst::<T>()?;
327
328        writer.write_all(
329            &(u32::try_from(self.len()).map_err(|_| ErrorKind::InvalidData)?).to_le_bytes(),
330        )?;
331        let slices = self.as_slices();
332        serialize_slice(slices.0, writer)?;
333        serialize_slice(slices.1, writer)
334    }
335}
336
337impl<T> BorshSerialize for LinkedList<T>
338where
339    T: BorshSerialize,
340{
341    #[inline]
342    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
343        check_zst::<T>()?;
344
345        writer.write_all(
346            &(u32::try_from(self.len()).map_err(|_| ErrorKind::InvalidData)?).to_le_bytes(),
347        )?;
348        for item in self {
349            item.serialize(writer)?;
350        }
351        Ok(())
352    }
353}
354
355/// Module is available if borsh is built with `features = ["std"]` or `features = ["hashbrown"]`.
356#[cfg(hash_collections)]
357pub mod hashes {
358    //!
359    //! Module defines [BorshSerialize] implementation for
360    //! [HashMap](std::collections::HashMap)/[HashSet](std::collections::HashSet).
361    use crate::__private::maybestd::vec::Vec;
362    use crate::error::check_zst;
363    use crate::{
364        BorshSerialize,
365        __private::maybestd::collections::{HashMap, HashSet},
366    };
367    use core::convert::TryFrom;
368    use core::hash::BuildHasher;
369
370    use crate::io::{ErrorKind, Result, Write};
371
372    impl<K, V, H> BorshSerialize for HashMap<K, V, H>
373    where
374        K: BorshSerialize + Ord,
375        V: BorshSerialize,
376        H: BuildHasher,
377    {
378        #[inline]
379        fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
380            check_zst::<K>()?;
381
382            let mut vec = self.iter().collect::<Vec<_>>();
383            vec.sort_by(|(a, _), (b, _)| a.cmp(b));
384            u32::try_from(vec.len())
385                .map_err(|_| ErrorKind::InvalidData)?
386                .serialize(writer)?;
387            for (key, value) in vec {
388                key.serialize(writer)?;
389                value.serialize(writer)?;
390            }
391            Ok(())
392        }
393    }
394
395    impl<T, H> BorshSerialize for HashSet<T, H>
396    where
397        T: BorshSerialize + Ord,
398        H: BuildHasher,
399    {
400        #[inline]
401        fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
402            check_zst::<T>()?;
403
404            let mut vec = self.iter().collect::<Vec<_>>();
405            vec.sort();
406            u32::try_from(vec.len())
407                .map_err(|_| ErrorKind::InvalidData)?
408                .serialize(writer)?;
409            for item in vec {
410                item.serialize(writer)?;
411            }
412            Ok(())
413        }
414    }
415}
416
417impl<K, V> BorshSerialize for BTreeMap<K, V>
418where
419    K: BorshSerialize,
420    V: BorshSerialize,
421{
422    #[inline]
423    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
424        check_zst::<K>()?;
425        // NOTE: BTreeMap iterates over the entries that are sorted by key, so the serialization
426        // result will be consistent without a need to sort the entries as we do for HashMap
427        // serialization.
428        u32::try_from(self.len())
429            .map_err(|_| ErrorKind::InvalidData)?
430            .serialize(writer)?;
431        for (key, value) in self {
432            key.serialize(writer)?;
433            value.serialize(writer)?;
434        }
435        Ok(())
436    }
437}
438
439impl<T> BorshSerialize for BTreeSet<T>
440where
441    T: BorshSerialize,
442{
443    #[inline]
444    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
445        check_zst::<T>()?;
446        // NOTE: BTreeSet iterates over the items that are sorted, so the serialization result will
447        // be consistent without a need to sort the entries as we do for HashSet serialization.
448        u32::try_from(self.len())
449            .map_err(|_| ErrorKind::InvalidData)?
450            .serialize(writer)?;
451        for item in self {
452            item.serialize(writer)?;
453        }
454        Ok(())
455    }
456}
457
458#[cfg(feature = "std")]
459impl BorshSerialize for std::net::SocketAddr {
460    #[inline]
461    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
462        match *self {
463            std::net::SocketAddr::V4(ref addr) => {
464                0u8.serialize(writer)?;
465                addr.serialize(writer)
466            }
467            std::net::SocketAddr::V6(ref addr) => {
468                1u8.serialize(writer)?;
469                addr.serialize(writer)
470            }
471        }
472    }
473}
474
475#[cfg(feature = "std")]
476impl BorshSerialize for std::net::SocketAddrV4 {
477    #[inline]
478    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
479        self.ip().serialize(writer)?;
480        self.port().serialize(writer)
481    }
482}
483
484#[cfg(feature = "std")]
485impl BorshSerialize for std::net::SocketAddrV6 {
486    #[inline]
487    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
488        self.ip().serialize(writer)?;
489        self.port().serialize(writer)
490    }
491}
492
493#[cfg(feature = "std")]
494impl BorshSerialize for std::net::Ipv4Addr {
495    #[inline]
496    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
497        writer.write_all(&self.octets())
498    }
499}
500
501#[cfg(feature = "std")]
502impl BorshSerialize for std::net::Ipv6Addr {
503    #[inline]
504    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
505        writer.write_all(&self.octets())
506    }
507}
508
509impl<T: BorshSerialize + ?Sized> BorshSerialize for Box<T> {
510    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
511        self.as_ref().serialize(writer)
512    }
513}
514
515impl<T, const N: usize> BorshSerialize for [T; N]
516where
517    T: BorshSerialize,
518{
519    #[inline]
520    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
521        if N == 0 {
522            return Ok(());
523        } else if let Some(u8_slice) = T::u8_slice(self) {
524            writer.write_all(u8_slice)?;
525        } else {
526            for el in self.iter() {
527                el.serialize(writer)?;
528            }
529        }
530        Ok(())
531    }
532}
533
534macro_rules! impl_tuple {
535    (@unit $name:ty) => {
536        impl BorshSerialize for $name {
537            #[inline]
538            fn serialize<W: Write>(&self, _writer: &mut W) -> Result<()> {
539                Ok(())
540            }
541        }
542    };
543
544    ($($idx:tt $name:ident)+) => {
545      impl<$($name),+> BorshSerialize for ($($name,)+)
546      where $($name: BorshSerialize,)+
547      {
548        #[inline]
549        fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
550            $(self.$idx.serialize(writer)?;)+
551            Ok(())
552        }
553      }
554    };
555}
556
557impl_tuple!(@unit ());
558impl_tuple!(@unit core::ops::RangeFull);
559
560impl_tuple!(0 T0);
561impl_tuple!(0 T0 1 T1);
562impl_tuple!(0 T0 1 T1 2 T2);
563impl_tuple!(0 T0 1 T1 2 T2 3 T3);
564impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4);
565impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5);
566impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6);
567impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7);
568impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8);
569impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9);
570impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10);
571impl_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);
572impl_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);
573impl_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);
574impl_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);
575impl_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);
576impl_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);
577impl_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);
578impl_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);
579impl_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);
580
581macro_rules! impl_range {
582    ($type:ident, $this:ident, $($field:expr),*) => {
583        impl<T: BorshSerialize> BorshSerialize for core::ops::$type<T> {
584            #[inline]
585            fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
586                let $this = self;
587                $( $field.serialize(writer)?; )*
588                Ok(())
589            }
590        }
591    };
592}
593
594impl_range!(Range, this, &this.start, &this.end);
595impl_range!(RangeInclusive, this, this.start(), this.end());
596impl_range!(RangeFrom, this, &this.start);
597impl_range!(RangeTo, this, &this.end);
598impl_range!(RangeToInclusive, this, &this.end);
599
600/// Module is available if borsh is built with `features = ["rc"]`.
601#[cfg(feature = "rc")]
602pub mod rc {
603    //!
604    //! Module defines [BorshSerialize] implementation for
605    //! [alloc::rc::Rc](std::rc::Rc) and [alloc::sync::Arc](std::sync::Arc).
606    use crate::__private::maybestd::{rc::Rc, sync::Arc};
607    use crate::io::{Result, Write};
608    use crate::BorshSerialize;
609
610    /// This impl requires the [`"rc"`] Cargo feature of borsh.
611    ///
612    /// Serializing a data structure containing `Rc` will serialize a copy of
613    /// the contents of the `Rc` each time the `Rc` is referenced within the
614    /// data structure. Serialization will not attempt to deduplicate these
615    /// repeated data.
616    impl<T: BorshSerialize + ?Sized> BorshSerialize for Rc<T> {
617        fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
618            (**self).serialize(writer)
619        }
620    }
621
622    /// This impl requires the [`"rc"`] Cargo feature of borsh.
623    ///
624    /// Serializing a data structure containing `Arc` will serialize a copy of
625    /// the contents of the `Arc` each time the `Arc` is referenced within the
626    /// data structure. Serialization will not attempt to deduplicate these
627    /// repeated data.
628    impl<T: BorshSerialize + ?Sized> BorshSerialize for Arc<T> {
629        fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
630            (**self).serialize(writer)
631        }
632    }
633}
634
635impl<T: ?Sized> BorshSerialize for PhantomData<T> {
636    fn serialize<W: Write>(&self, _: &mut W) -> Result<()> {
637        Ok(())
638    }
639}
640
641impl<T> BorshSerialize for core::cell::Cell<T>
642where
643    T: BorshSerialize + Copy,
644{
645    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
646        <T as BorshSerialize>::serialize(&self.get(), writer)
647    }
648}
649
650impl<T> BorshSerialize for core::cell::RefCell<T>
651where
652    T: BorshSerialize + Sized,
653{
654    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
655        match self.try_borrow() {
656            Ok(ref value) => value.serialize(writer),
657            Err(_) => Err(Error::new(ErrorKind::Other, "already mutably borrowed")),
658        }
659    }
660}