borsh/ser/helpers.rs
1use crate::BorshSerialize;
2use crate::__private::maybestd::vec::Vec;
3use crate::io::{ErrorKind, Result, Write};
4
5pub(super) const DEFAULT_SERIALIZER_CAPACITY: usize = 1024;
6
7/// Serialize an object into a vector of bytes.
8/// # Example
9///
10/// ```
11/// assert_eq!(vec![12, 0, 0, 0, 0, 0, 0, 0], borsh::to_vec(&12u64).unwrap());
12/// ```
13pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
14where
15 T: BorshSerialize + ?Sized,
16{
17 let mut result = Vec::with_capacity(DEFAULT_SERIALIZER_CAPACITY);
18 value.serialize(&mut result)?;
19 Ok(result)
20}
21
22/// Serializes an object directly into a `Writer`.
23/// # Example
24///
25/// ```
26/// # #[cfg(feature = "std")]
27/// let stderr = std::io::stderr();
28/// # #[cfg(feature = "std")]
29/// assert_eq!((), borsh::to_writer(&stderr, "hello_0x0a").unwrap());
30/// ```
31pub fn to_writer<T, W: Write>(mut writer: W, value: &T) -> Result<()>
32where
33 T: BorshSerialize + ?Sized,
34{
35 value.serialize(&mut writer)
36}
37
38/// Serializes an object without allocation to compute and return its length
39/// # Example
40///
41/// ```
42/// use borsh::BorshSerialize;
43///
44/// /// derive is only available if borsh is built with `features = ["derive"]`
45/// # #[cfg(feature = "derive")]
46/// #[derive(BorshSerialize)]
47/// struct A {
48/// tag: String,
49/// value: u64,
50/// };
51///
52/// # #[cfg(feature = "derive")]
53/// let a = A { tag: "hello".to_owned(), value: 42 };
54///
55/// assert_eq!(8, borsh::object_length(&12u64).unwrap());
56/// # #[cfg(feature = "derive")]
57/// assert_eq!(17, borsh::object_length(&a).unwrap());
58/// ```
59pub fn object_length<T>(value: &T) -> Result<usize>
60where
61 T: BorshSerialize + ?Sized,
62{
63 // copy-paste of solution provided by @matklad
64 // in https://github.com/near/borsh-rs/issues/23#issuecomment-816633365
65 struct LengthWriter {
66 len: usize,
67 }
68 impl Write for LengthWriter {
69 #[inline]
70 fn write(&mut self, buf: &[u8]) -> Result<usize> {
71 let res = self.len.checked_add(buf.len());
72 self.len = match res {
73 Some(res) => res,
74 None => {
75 return Err(ErrorKind::OutOfMemory.into());
76 }
77 };
78 Ok(buf.len())
79 }
80 #[inline]
81 fn flush(&mut self) -> Result<()> {
82 Ok(())
83 }
84 }
85 let mut w = LengthWriter { len: 0 };
86 value.serialize(&mut w)?;
87 Ok(w.len)
88}