Improve optional support for borsh serialization

- Do not allocate when deserializing ArrayString
- Serialize length as u32, not as u64, to be consistent with
  serialization of [T] and str
- Add tests
This commit is contained in:
Jan Špaček
2024-01-18 10:15:50 +01:00
committed by bluss
parent 4337b1bdd7
commit ae6cfd3baf
4 changed files with 93 additions and 16 deletions
+15 -6
View File
@@ -640,13 +640,22 @@ impl<const CAP: usize> borsh::BorshSerialize for ArrayString<CAP> {
/// Requires crate feature `"borsh"`
impl<const CAP: usize> borsh::BorshDeserialize for ArrayString<CAP> {
fn deserialize_reader<R: borsh::io::Read>(reader: &mut R) -> borsh::io::Result<Self> {
let s = <String as borsh::BorshDeserialize>::deserialize_reader(reader)?;
ArrayString::from(&s).map_err(|_| {
borsh::io::Error::new(
let len = <u32 as borsh::BorshDeserialize>::deserialize_reader(reader)? as usize;
if len > CAP {
return Err(borsh::io::Error::new(
borsh::io::ErrorKind::InvalidData,
format!("expected a string no more than {} bytes long", CAP),
)
})
format!("Expected a string no more than {} bytes long", CAP),
))
}
let mut buf = [0u8; CAP];
let buf = &mut buf[..len];
reader.read_exact(buf)?;
let s = str::from_utf8(&buf).map_err(|err| {
borsh::io::Error::new(borsh::io::ErrorKind::InvalidData, err.to_string())
})?;
Ok(Self::from(s).unwrap())
}
}
+3 -8
View File
@@ -1309,12 +1309,7 @@ where
T: borsh::BorshSerialize,
{
fn serialize<W: borsh::io::Write>(&self, writer: &mut W) -> borsh::io::Result<()> {
let vs = self.as_slice();
<usize as borsh::BorshSerialize>::serialize(&vs.len(), writer)?;
for elem in vs {
<T as borsh::BorshSerialize>::serialize(elem, writer)?;
}
Ok(())
<[T] as borsh::BorshSerialize>::serialize(self.as_slice(), writer)
}
}
@@ -1326,13 +1321,13 @@ where
{
fn deserialize_reader<R: borsh::io::Read>(reader: &mut R) -> borsh::io::Result<Self> {
let mut values = Self::new();
let len = <usize as borsh::BorshDeserialize>::deserialize_reader(reader)?;
let len = <u32 as borsh::BorshDeserialize>::deserialize_reader(reader)?;
for _ in 0..len {
let elem = <T as borsh::BorshDeserialize>::deserialize_reader(reader)?;
if let Err(_) = values.try_push(elem) {
return Err(borsh::io::Error::new(
borsh::io::ErrorKind::InvalidData,
format!("expected an array with no more than {} items", CAP),
format!("Expected an array with no more than {} items", CAP),
));
}
}