use { borsh::{BorshDeserialize, BorshSerialize}, serde::{ de::DeserializeSeed, ser::{SerializeSeq, SerializeStruct}, Deserialize, Serialize, }, }; /// PrefixlessVec overrides the serialization to _not_ write a length prefix. #[derive(Clone, Debug, Hash, PartialEq, PartialOrd, BorshDeserialize, BorshSerialize)] struct PrefixlessVec { inner: Vec, } impl Serialize for PrefixlessVec where T: Serialize, { #[inline] fn serialize(&self, serializer: S) -> Result { let mut seq = serializer.serialize_seq(None)?; for item in &self.inner { seq.serialize_element(item)?; } seq.end() } } struct PrefixlessSeed { __phantom: std::marker::PhantomData, len: usize, } /// We implement DeserializeSeed for PrefixlessSeed which is aware of the len that should be read /// for the Vec, this len would have been found previously during parsing the PrefixedVec which /// will drive this deserializer forward. The result is a PrefixlessVec which is intended to /// be read by the PrefixedVec deserializer. impl<'de, T> DeserializeSeed<'de> for PrefixlessSeed where T: Deserialize<'de>, { type Value = PrefixlessVec; fn deserialize>( self, deserializer: D, ) -> Result { struct PrefixlessVecVisitor { len: usize, __phantom: std::marker::PhantomData, } impl<'de, T> serde::de::Visitor<'de> for PrefixlessVecVisitor where T: Deserialize<'de>, { type Value = PrefixlessVec; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("struct PrefixlessVec") } #[inline] fn visit_seq(self, mut seq: V) -> Result, V::Error> where V: serde::de::SeqAccess<'de>, { let mut data = Vec::with_capacity(self.len); for i in 0..self.len { data.push( seq.next_element::()? .ok_or_else(|| serde::de::Error::invalid_length(i, &"PrefixlessVec"))?, ); } Ok(PrefixlessVec { inner: data }) } } deserializer.deserialize_tuple( self.len, PrefixlessVecVisitor { len: self.len, __phantom: std::marker::PhantomData, }, ) } } /// PrefixedVec allows overriding the default u8 size of the length prefix for a Vec. /// /// This is useful when the size of a Vec is greater than 255 and we wish to override the /// Pyth serialization logic to use a u16 etc instead. This works by serializing the Vec /// as a struct with a len field with the overridden type, when combined with PrefixlessVec /// below the combination of `{ "len": L, "data": [T] }` is serialized as expected in the /// wire format. /// /// For non-Pyth formats this results in a struct which is the correct way to interpret our /// data on chain anyway. #[derive(Clone, Debug, Hash, PartialEq, PartialOrd, BorshDeserialize, BorshSerialize)] pub struct PrefixedVec { __phantom: std::marker::PhantomData, data: PrefixlessVec, } impl From> for PrefixedVec { fn from(data: Vec) -> Self { Self { __phantom: std::marker::PhantomData, data: PrefixlessVec { inner: data }, } } } impl From> for Vec { fn from(data: PrefixedVec) -> Self { data.data.inner } } impl AsRef> for PrefixedVec { fn as_ref(&self) -> &Vec { &self.data.inner } } impl IntoIterator for PrefixedVec { type Item = T; type IntoIter = std::vec::IntoIter; fn into_iter(self) -> Self::IntoIter { self.data.inner.into_iter() } } impl PrefixedVec { pub fn iter(&self) -> std::slice::Iter { self.data.inner.iter() } } impl Serialize for PrefixedVec where T: Serialize, L: Serialize, L: TryFrom, >::Error: std::fmt::Debug, { #[inline] fn serialize(&self, serializer: S) -> Result { let len: L = L::try_from(self.data.inner.len()).unwrap(); let mut st = serializer.serialize_struct("SizedVec", 1)?; st.serialize_field("len", &len)?; st.serialize_field("data", &self.data)?; st.end() } } impl<'de, L, T> Deserialize<'de> for PrefixedVec where T: Deserialize<'de>, L: Deserialize<'de>, L: Into, L: Copy, { #[inline] fn deserialize>(deserializer: D) -> Result { #[derive(Deserialize)] #[serde(field_identifier, rename_all = "lowercase")] enum Field { Len, Data, } struct PrefixedVecVisitor { __phantom: std::marker::PhantomData<(L, T)>, } impl<'de, L, T> serde::de::Visitor<'de> for PrefixedVecVisitor where T: Deserialize<'de>, L: Deserialize<'de>, L: Into, L: Copy, { type Value = PrefixedVec; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("struct PrefixedVec") } #[inline] fn visit_seq(self, mut seq: V) -> Result, V::Error> where V: serde::de::SeqAccess<'de>, { // First we parse the expected size type from the wire format. let len: usize = seq .next_element::()? .ok_or_else(|| serde::de::Error::invalid_length(0, &"PrefixlessVec"))? .into(); // We now rely on the PrefixlessVec deserializer to do the rest of the work. We // need to use the PrefixlessSeed to pass the expected size to the deserializer. let data = seq .next_element_seed(PrefixlessSeed { __phantom: std::marker::PhantomData, len, })? .ok_or_else(|| serde::de::Error::invalid_length(1, &"PrefixlessVec"))?; Ok(PrefixedVec { __phantom: std::marker::PhantomData, data, }) } } deserializer.deserialize_struct( "PrefixedVec", &["len", "data"], PrefixedVecVisitor { __phantom: std::marker::PhantomData, }, ) } } #[test] fn test_borsh_roundtrip() { let prefixed_vec = PrefixedVec::::from(vec![1, 2, 3, 4, 5]); let encoded = borsh::to_vec(&prefixed_vec).unwrap(); assert_eq!(encoded, vec![5, 0, 0, 0, 1, 2, 3, 4, 5]); let decoded_prefixed_vec = PrefixedVec::::try_from_slice(encoded.as_slice()).unwrap(); assert_eq!(decoded_prefixed_vec, prefixed_vec); }