1use std::collections::{BTreeMap, HashMap, HashSet};
2use std::io::{Error, Write};
3
4const DEFAULT_SERIALIZER_CAPACITY: usize = 1024;
5
6pub trait BorshSerialize {
8 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error>;
9
10 fn try_to_vec(&self) -> Result<Vec<u8>, Error> {
12 let mut result = Vec::with_capacity(DEFAULT_SERIALIZER_CAPACITY);
13 self.serialize(&mut result)?;
14 Ok(result)
15 }
16}
17
18impl BorshSerialize for () {
19 fn serialize<W: Write>(&self, _writer: &mut W) -> Result<(), Error> {
20 Ok(())
21 }
22}
23
24impl BorshSerialize for u8 {
25 #[inline]
26 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
27 writer.write_all(std::slice::from_ref(self))
28 }
29}
30
31macro_rules! impl_for_integer {
32 ($type: ident) => {
33 impl BorshSerialize for $type {
34 #[inline]
35 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
36 writer.write_all(&self.to_le_bytes())
37 }
38 }
39 };
40}
41
42impl_for_integer!(i8);
43impl_for_integer!(i16);
44impl_for_integer!(i32);
45impl_for_integer!(i64);
46impl_for_integer!(i128);
47impl_for_integer!(u16);
48impl_for_integer!(u32);
49impl_for_integer!(u64);
50impl_for_integer!(u128);
51
52macro_rules! impl_for_float {
55 ($type: ident) => {
56 impl BorshSerialize for $type {
57 #[inline]
58 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
59 assert!(
60 !self.is_nan(),
61 "For portability reasons we do not allow to serialize NaNs."
62 );
63 writer.write_all(&self.to_bits().to_le_bytes())
64 }
65 }
66 };
67}
68
69impl_for_float!(f32);
70impl_for_float!(f64);
71
72impl BorshSerialize for bool {
73 #[inline]
74 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
75 (if *self { 1u8 } else { 0u8 }).serialize(writer)
76 }
77}
78
79impl<T> BorshSerialize for Option<T>
80where
81 T: BorshSerialize,
82{
83 #[inline]
84 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
85 match self {
86 None => 0u8.serialize(writer),
87 Some(value) => {
88 1u8.serialize(writer)?;
89 value.serialize(writer)
90 }
91 }
92 }
93}
94
95impl<T, E> BorshSerialize for Result<T, E>
96where
97 T: BorshSerialize,
98 E: BorshSerialize,
99{
100 #[inline]
101 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
102 match self {
103 Ok(value) => {
104 0u8.serialize(writer)?;
105 value.serialize(writer)
106 },
107 Err(value) => {
108 1u8.serialize(writer)?;
109 value.serialize(writer)
110 }
111 }
112 }
113}
114
115impl BorshSerialize for String {
116 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
117 self.as_bytes().serialize(writer)
118 }
119}
120
121impl BorshSerialize for &str {
122 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
123 self.as_bytes().serialize(writer)
124 }
125}
126
127#[cfg(feature = "std")]
128impl<T: BorshSerialize> BorshSerialize for Vec<T> {
129 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
130 self.as_slice().serialize(writer)
131 }
132}
133
134impl<T> BorshSerialize for [T]
135where
136 T: BorshSerialize,
137{
138 #[inline]
139 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
140 writer.write_all(&(self.len() as u32).to_le_bytes())?;
141 for item in self {
142 item.serialize(writer)?;
143 }
144 Ok(())
145 }
146}
147
148
149impl<T> BorshSerialize for &[T]
150where
151 T: BorshSerialize,
152{
153 #[inline]
154 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
155 writer.write_all(&(self.len() as u32).to_le_bytes())?;
156 for item in self.iter() {
157 item.serialize(writer)?;
158 }
159 Ok(())
160 }
161}
162
163impl<T: BorshSerialize> BorshSerialize for &T {
164 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
165 (*self).serialize(writer)
166 }
167}
168
169#[cfg(feature = "std")]
170impl<T, S> BorshSerialize for HashSet<T, S>
171where
172 T: BorshSerialize + PartialOrd,
173 S: std::hash::BuildHasher,
174{
175 #[inline]
176 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
177 let mut vec = self.iter().collect::<Vec<_>>();
178 vec.sort_by(|a, b| a.partial_cmp(b).unwrap());
179 (vec.len() as u32).serialize(writer)?;
180 for item in vec {
181 item.serialize(writer)?;
182 }
183 Ok(())
184 }
185}
186
187#[cfg(feature = "std")]
188impl<K, V, S> BorshSerialize for HashMap<K, V, S>
189where
190 K: BorshSerialize + PartialOrd,
191 V: BorshSerialize,
192 S: std::hash::BuildHasher,
193{
194 #[inline]
195 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
196 let mut vec = self.iter().collect::<Vec<_>>();
197 vec.sort_by(|(a, _), (b, _)| a.partial_cmp(b).unwrap());
198 (vec.len() as u32).serialize(writer)?;
199 for (key, value) in vec {
200 key.serialize(writer)?;
201 value.serialize(writer)?;
202 }
203 Ok(())
204 }
205}
206
207#[cfg(feature = "std")]
208impl<K, V> BorshSerialize for BTreeMap<K, V>
209where
210 K: BorshSerialize + PartialOrd,
211 V: BorshSerialize,
212{
213 #[inline]
214 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
215 (self.len() as u32).serialize(writer)?;
216 for (key, value) in self.iter() {
217 key.serialize(writer)?;
218 value.serialize(writer)?;
219 }
220 Ok(())
221 }
222}
223
224#[cfg(feature = "std")]
225impl BorshSerialize for std::net::SocketAddr {
226 #[inline]
227 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
228 match *self {
229 std::net::SocketAddr::V4(ref addr) => {
230 0u8.serialize(writer)?;
231 addr.serialize(writer)
232 }
233 std::net::SocketAddr::V6(ref addr) => {
234 1u8.serialize(writer)?;
235 addr.serialize(writer)
236 }
237 }
238 }
239}
240
241#[cfg(feature = "std")]
242impl BorshSerialize for std::net::SocketAddrV4 {
243 #[inline]
244 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
245 self.ip().serialize(writer)?;
246 self.port().serialize(writer)
247 }
248}
249
250#[cfg(feature = "std")]
251impl BorshSerialize for std::net::SocketAddrV6 {
252 #[inline]
253 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
254 self.ip().serialize(writer)?;
255 self.port().serialize(writer)
256 }
257}
258
259#[cfg(feature = "std")]
260impl BorshSerialize for std::net::Ipv4Addr {
261 #[inline]
262 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
263 writer.write_all(&self.octets())
264 }
265}
266
267#[cfg(feature = "std")]
268impl BorshSerialize for std::net::Ipv6Addr {
269 #[inline]
270 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
271 writer.write_all(&self.octets())
272 }
273}
274
275impl BorshSerialize for Box<[u8]> {
276 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
277 (self.len() as u32).serialize(writer)?;
278 writer.write_all(self)
279 }
280}
281
282impl<T: BorshSerialize> BorshSerialize for Box<T> {
283 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
284 (&**self).serialize(writer)
285 }
286}
287
288macro_rules! impl_arrays {
289 ($($len:expr)+) => {
290 $(
291 impl<T> BorshSerialize for [T; $len]
292 where T: BorshSerialize
293 {
294 #[inline]
295 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
296 for el in self.iter() {
297 el.serialize(writer)?;
298 }
299 Ok(())
300 }
301 }
302 )+
303 };
304}
305
306impl_arrays!(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 32 64 65);
307
308macro_rules! impl_tuple {
309 ($($idx:tt $name:ident)+) => {
310 impl<$($name),+> BorshSerialize for ($($name),+)
311 where $($name: BorshSerialize,)+
312 {
313 #[inline]
314 fn serialize<W: Write>(&self, writer: &mut W) -> Result<(), Error> {
315 $(self.$idx.serialize(writer)?;)+
316 Ok(())
317 }
318 }
319 };
320}
321
322impl_tuple!(0 T0 1 T1);
323impl_tuple!(0 T0 1 T1 2 T2);
324impl_tuple!(0 T0 1 T1 2 T2 3 T3);
325impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4);
326impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5);
327impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6);
328impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7);
329impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8);
330impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9);
331impl_tuple!(0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10);
332impl_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);
333impl_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);
334impl_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);
335impl_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);
336impl_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);
337impl_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);
338impl_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);
339impl_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);
340impl_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);