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