Skip to content

Instantly share code, notes, and snippets.

@alexreg
Created February 5, 2022 17:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexreg/36f04712760707079eda29475e35045e to your computer and use it in GitHub Desktop.
Save alexreg/36f04712760707079eda29475e35045e to your computer and use it in GitHub Desktop.
use std::{
io::{Result, Write},
iter::{ExactSizeIterator, FromIterator, IntoIterator},
};
use super::{de::BorshDeserialize, ser::BorshSerialize};
/// Conversion into an `Iterator` with a canonical ordering of items.
pub trait IntoCanonicalIterator: IntoIterator {
// Note: no default impl because we cannot assume that `into_iter` yields canonical ordering.
fn into_canon_iter(self) -> Self::IntoIter;
}
/// Conversion from an `Iterator` with a canonical ordering of items.
pub trait FromCanonicalIterator<A>: FromIterator<A> {
// Note: no default impl because we cannot assume that `iter` has canonical ordering.
fn from_canon_iter<T>(iter: T) -> Self
where
T: IntoCanonicalIterator<Item = A>;
}
impl<T: IntoCanonicalIterator> BorshSerialize for T
where
T::Item: BorshSerialize,
{
fn serialize<W: Write>(&self, writer: &mut W) -> Result<()> {
let iter = self.into_canon_iter();
iter.len().serialize(writer)?;
for item in iter {
item.serialize(writer)?;
}
Ok(())
}
}
impl<T: FromCanonicalIterator<A>, A> BorshDeserialize for T
where
T: IntoCanonicalIterator<Item = A>,
A: BorshDeserialize,
{
fn deserialize(buf: &mut &[u8]) -> Result<Self>
where
T: IntoCanonicalIterator<Item = A>,
{
let len = usize::deserialize(buf)?;
Self::from_canon_iter(|| {
for i in 0 .. len {
yield A::deserialize();
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment