Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'lib/smol_str/src/borsh.rs')
| -rw-r--r-- | lib/smol_str/src/borsh.rs | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/lib/smol_str/src/borsh.rs b/lib/smol_str/src/borsh.rs new file mode 100644 index 0000000000..527ce85a17 --- /dev/null +++ b/lib/smol_str/src/borsh.rs @@ -0,0 +1,40 @@ +use crate::{INLINE_CAP, Repr, SmolStr}; +use alloc::string::{String, ToString}; +use borsh::{ + BorshDeserialize, BorshSerialize, + io::{Error, ErrorKind, Read, Write}, +}; +use core::mem::transmute; + +impl BorshSerialize for SmolStr { + fn serialize<W: Write>(&self, writer: &mut W) -> borsh::io::Result<()> { + self.as_str().serialize(writer) + } +} + +impl BorshDeserialize for SmolStr { + #[inline] + fn deserialize_reader<R: Read>(reader: &mut R) -> borsh::io::Result<Self> { + let len = u32::deserialize_reader(reader)?; + if (len as usize) < INLINE_CAP { + let mut buf = [0u8; INLINE_CAP]; + reader.read_exact(&mut buf[..len as usize])?; + _ = core::str::from_utf8(&buf[..len as usize]).map_err(|err| { + let msg = err.to_string(); + Error::new(ErrorKind::InvalidData, msg) + })?; + Ok(SmolStr(Repr::Inline { + len: unsafe { transmute::<u8, crate::InlineSize>(len as u8) }, + buf, + })) + } else { + // u8::vec_from_reader always returns Some on success in current implementation + let vec = u8::vec_from_reader(len, reader)? + .ok_or_else(|| Error::other("u8::vec_from_reader unexpectedly returned None"))?; + Ok(SmolStr::from(String::from_utf8(vec).map_err(|err| { + let msg = err.to_string(); + Error::new(ErrorKind::InvalidData, msg) + })?)) + } + } +} |