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///
357/// Module defines [BorshSerialize] implementation for
358/// [HashMap](std::collections::HashMap)/[HashSet](std::collections::HashSet).
359#[cfg(hash_collections)]
360pub mod hashes {
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 kv in vec {
388                kv.serialize(writer)?;
389            }
390            Ok(())
391        }
392    }
393
394    impl<T, H> BorshSerialize for HashSet<T, H>
395    where
396        T: BorshSerialize + Ord,
397        H: BuildHasher,
398    {
399        #[inline]
400        fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
401            check_zst::<T>()?;
402
403            let mut vec = self.iter().collect::<Vec<_>>();
404            vec.sort();
405            u32::try_from(vec.len())
406                .map_err(|_| ErrorKind::InvalidData)?
407                .serialize(writer)?;
408            for item in vec {
409                item.serialize(writer)?;
410            }
411            Ok(())
412        }
413    }
414}
415
416impl<K, V> BorshSerialize for BTreeMap<K, V>
417where
418    K: BorshSerialize,
419    V: BorshSerialize,
420{
421    #[inline]
422    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
423        check_zst::<K>()?;
424        // NOTE: BTreeMap iterates over the entries that are sorted by key, so the serialization
425        // result will be consistent without a need to sort the entries as we do for HashMap
426        // serialization.
427        u32::try_from(self.len())
428            .map_err(|_| ErrorKind::InvalidData)?
429            .serialize(writer)?;
430        for (key, value) in self {
431            key.serialize(writer)?;
432            value.serialize(writer)?;
433        }
434        Ok(())
435    }
436}
437
438impl<T> BorshSerialize for BTreeSet<T>
439where
440    T: BorshSerialize,
441{
442    #[inline]
443    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
444        check_zst::<T>()?;
445        // NOTE: BTreeSet iterates over the items that are sorted, so the serialization result will
446        // be consistent without a need to sort the entries as we do for HashSet serialization.
447        u32::try_from(self.len())
448            .map_err(|_| ErrorKind::InvalidData)?
449            .serialize(writer)?;
450        for item in self {
451            item.serialize(writer)?;
452        }
453        Ok(())
454    }
455}
456
457#[cfg(feature = "std")]
458impl BorshSerialize for std::net::SocketAddr {
459    #[inline]
460    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
461        match *self {
462            std::net::SocketAddr::V4(ref addr) => {
463                0u8.serialize(writer)?;
464                addr.serialize(writer)
465            }
466            std::net::SocketAddr::V6(ref addr) => {
467                1u8.serialize(writer)?;
468                addr.serialize(writer)
469            }
470        }
471    }
472}
473
474#[cfg(feature = "std")]
475impl BorshSerialize for std::net::SocketAddrV4 {
476    #[inline]
477    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
478        self.ip().serialize(writer)?;
479        self.port().serialize(writer)
480    }
481}
482
483#[cfg(feature = "std")]
484impl BorshSerialize for std::net::SocketAddrV6 {
485    #[inline]
486    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
487        self.ip().serialize(writer)?;
488        self.port().serialize(writer)
489    }
490}
491
492#[cfg(feature = "std")]
493impl BorshSerialize for std::net::Ipv4Addr {
494    #[inline]
495    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
496        writer.write_all(&self.octets())
497    }
498}
499
500#[cfg(feature = "std")]
501impl BorshSerialize for std::net::Ipv6Addr {
502    #[inline]
503    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
504        writer.write_all(&self.octets())
505    }
506}
507
508#[cfg(feature = "std")]
509impl BorshSerialize for std::net::IpAddr {
510    #[inline]
511    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
512        match self {
513            std::net::IpAddr::V4(ipv4) => {
514                writer.write_all(&0u8.to_le_bytes())?;
515                ipv4.serialize(writer)
516            }
517            std::net::IpAddr::V6(ipv6) => {
518                writer.write_all(&1u8.to_le_bytes())?;
519                ipv6.serialize(writer)
520            }
521        }
522    }
523}
524impl<T: BorshSerialize + ?Sized> BorshSerialize for Box<T> {
525    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
526        self.as_ref().serialize(writer)
527    }
528}
529
530impl<T, const N: usize> BorshSerialize for [T; N]
531where
532    T: BorshSerialize,
533{
534    #[inline]
535    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
536        if N == 0 {
537            return Ok(());
538        } else if let Some(u8_slice) = T::u8_slice(self) {
539            writer.write_all(u8_slice)?;
540        } else {
541            for el in self.iter() {
542                el.serialize(writer)?;
543            }
544        }
545        Ok(())
546    }
547}
548
549macro_rules! impl_tuple {
550    (@unit $name:ty) => {
551        impl BorshSerialize for $name {
552            #[inline]
553            fn serialize<W: Write>(&self, _writer: &mut W) -> Result<()> {
554                Ok(())
555            }
556        }
557    };
558
559    ($($idx:tt $name:ident)+) => {
560      impl<$($name),+> BorshSerialize for ($($name,)+)
561      where $($name: BorshSerialize,)+
562      {
563        #[inline]
564        fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
565            $(self.$idx.serialize(writer)?;)+
566            Ok(())
567        }
568      }
569    };
570}
571
572impl_tuple!(@unit ());
573impl_tuple!(@unit core::ops::RangeFull);
574
575impl_tuple!(0 T0);
576impl_tuple!(0 T0 1 T1);
577impl_tuple!(0 T0 1 T1 2 T2);
578impl_tuple!(0 T0 1 T1 2 T2 3 T3);
579impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4);
580impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5);
581impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6);
582impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7);
583impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8);
584impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9);
585impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10);
586impl_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);
587impl_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);
588impl_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);
589impl_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);
590impl_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);
591impl_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);
592impl_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);
593impl_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);
594impl_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);
595
596macro_rules! impl_range {
597    ($type:ident, $this:ident, $($field:expr),*) => {
598        impl<T: BorshSerialize> BorshSerialize for core::ops::$type<T> {
599            #[inline]
600            fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
601                let $this = self;
602                $( $field.serialize(writer)?; )*
603                Ok(())
604            }
605        }
606    };
607}
608
609impl_range!(Range, this, &this.start, &this.end);
610impl_range!(RangeInclusive, this, this.start(), this.end());
611impl_range!(RangeFrom, this, &this.start);
612impl_range!(RangeTo, this, &this.end);
613impl_range!(RangeToInclusive, this, &this.end);
614
615/// Module is available if borsh is built with `features = ["rc"]`.
616#[cfg(feature = "rc")]
617pub mod rc {
618    //!
619    //! Module defines [BorshSerialize] implementation for
620    //! [alloc::rc::Rc](std::rc::Rc) and [alloc::sync::Arc](std::sync::Arc).
621    use crate::__private::maybestd::{rc::Rc, sync::Arc};
622    use crate::io::{Result, Write};
623    use crate::BorshSerialize;
624
625    /// This impl requires the [`"rc"`] Cargo feature of borsh.
626    ///
627    /// Serializing a data structure containing `Rc` will serialize a copy of
628    /// the contents of the `Rc` each time the `Rc` is referenced within the
629    /// data structure. Serialization will not attempt to deduplicate these
630    /// repeated data.
631    impl<T: BorshSerialize + ?Sized> BorshSerialize for Rc<T> {
632        fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
633            (**self).serialize(writer)
634        }
635    }
636
637    /// This impl requires the [`"rc"`] Cargo feature of borsh.
638    ///
639    /// Serializing a data structure containing `Arc` will serialize a copy of
640    /// the contents of the `Arc` each time the `Arc` is referenced within the
641    /// data structure. Serialization will not attempt to deduplicate these
642    /// repeated data.
643    impl<T: BorshSerialize + ?Sized> BorshSerialize for Arc<T> {
644        fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
645            (**self).serialize(writer)
646        }
647    }
648}
649
650impl<T: ?Sized> BorshSerialize for PhantomData<T> {
651    fn serialize<W: Write>(&self, _: &mut W) -> Result<()> {
652        Ok(())
653    }
654}
655
656impl<T> BorshSerialize for core::cell::Cell<T>
657where
658    T: BorshSerialize + Copy,
659{
660    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
661        <T as BorshSerialize>::serialize(&self.get(), writer)
662    }
663}
664
665impl<T> BorshSerialize for core::cell::RefCell<T>
666where
667    T: BorshSerialize + Sized,
668{
669    fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
670        match self.try_borrow() {
671            Ok(ref value) => value.serialize(writer),
672            Err(_) => Err(Error::new(ErrorKind::Other, "already mutably borrowed")),
673        }
674    }
675}