pythnet_sdk/wire/
prefixed_vec.rs

1use {
2    borsh::{BorshDeserialize, BorshSerialize},
3    serde::{
4        de::DeserializeSeed,
5        ser::{SerializeSeq, SerializeStruct},
6        Deserialize, Serialize,
7    },
8};
9
10/// PrefixlessVec overrides the serialization to _not_ write a length prefix.
11#[derive(Clone, Debug, Hash, PartialEq, PartialOrd, BorshDeserialize, BorshSerialize)]
12struct PrefixlessVec<T> {
13    inner: Vec<T>,
14}
15
16impl<T> Serialize for PrefixlessVec<T>
17where
18    T: Serialize,
19{
20    #[inline]
21    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
22        let mut seq = serializer.serialize_seq(None)?;
23        for item in &self.inner {
24            seq.serialize_element(item)?;
25        }
26        seq.end()
27    }
28}
29
30struct PrefixlessSeed<T> {
31    __phantom: std::marker::PhantomData<T>,
32    len: usize,
33}
34
35/// We implement DeserializeSeed for PrefixlessSeed which is aware of the len that should be read
36/// for the Vec, this len would have been found previously during parsing the PrefixedVec which
37/// will drive this deserializer forward. The result is a PrefixlessVec<T> which is intended to
38/// be read by the PrefixedVec deserializer.
39impl<'de, T> DeserializeSeed<'de> for PrefixlessSeed<T>
40where
41    T: Deserialize<'de>,
42{
43    type Value = PrefixlessVec<T>;
44
45    fn deserialize<D: serde::Deserializer<'de>>(
46        self,
47        deserializer: D,
48    ) -> Result<Self::Value, D::Error> {
49        struct PrefixlessVecVisitor<T> {
50            len: usize,
51            __phantom: std::marker::PhantomData<T>,
52        }
53
54        impl<'de, T> serde::de::Visitor<'de> for PrefixlessVecVisitor<T>
55        where
56            T: Deserialize<'de>,
57        {
58            type Value = PrefixlessVec<T>;
59
60            fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
61                formatter.write_str("struct PrefixlessVec")
62            }
63
64            #[inline]
65            fn visit_seq<V>(self, mut seq: V) -> Result<PrefixlessVec<T>, V::Error>
66            where
67                V: serde::de::SeqAccess<'de>,
68            {
69                let mut data = Vec::with_capacity(self.len);
70                for i in 0..self.len {
71                    data.push(
72                        seq.next_element::<T>()?
73                            .ok_or_else(|| serde::de::Error::invalid_length(i, &"PrefixlessVec"))?,
74                    );
75                }
76
77                Ok(PrefixlessVec { inner: data })
78            }
79        }
80
81        deserializer.deserialize_tuple(
82            self.len,
83            PrefixlessVecVisitor {
84                len: self.len,
85                __phantom: std::marker::PhantomData,
86            },
87        )
88    }
89}
90
91/// PrefixedVec allows overriding the default u8 size of the length prefix for a Vec.
92///
93/// This is useful when the size of a Vec is greater than 255 and we wish to override the
94/// Pyth serialization logic to use a u16 etc instead. This works by serializing the Vec
95/// as a struct with a len field with the overridden type, when combined with PrefixlessVec
96/// below the combination of `{ "len": L, "data": [T] }` is serialized as expected in the
97/// wire format.
98///
99/// For non-Pyth formats this results in a struct which is the correct way to interpret our
100/// data on chain anyway.
101#[derive(Clone, Debug, Hash, PartialEq, PartialOrd, BorshDeserialize, BorshSerialize)]
102pub struct PrefixedVec<L, T> {
103    __phantom: std::marker::PhantomData<L>,
104    data: PrefixlessVec<T>,
105}
106
107impl<L, T> From<Vec<T>> for PrefixedVec<L, T> {
108    fn from(data: Vec<T>) -> Self {
109        Self {
110            __phantom: std::marker::PhantomData,
111            data: PrefixlessVec { inner: data },
112        }
113    }
114}
115
116impl<L, T> From<PrefixedVec<L, T>> for Vec<T> {
117    fn from(data: PrefixedVec<L, T>) -> Self {
118        data.data.inner
119    }
120}
121
122impl<L, T> AsRef<Vec<T>> for PrefixedVec<L, T> {
123    fn as_ref(&self) -> &Vec<T> {
124        &self.data.inner
125    }
126}
127
128impl<L, T> IntoIterator for PrefixedVec<L, T> {
129    type Item = T;
130    type IntoIter = std::vec::IntoIter<Self::Item>;
131
132    fn into_iter(self) -> Self::IntoIter {
133        self.data.inner.into_iter()
134    }
135}
136
137impl<L, T> PrefixedVec<L, T> {
138    pub fn iter(&self) -> std::slice::Iter<T> {
139        self.data.inner.iter()
140    }
141}
142
143impl<L, T> Serialize for PrefixedVec<L, T>
144where
145    T: Serialize,
146    L: Serialize,
147    L: TryFrom<usize>,
148    <L as TryFrom<usize>>::Error: std::fmt::Debug,
149{
150    #[inline]
151    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
152        let len: L = L::try_from(self.data.inner.len()).unwrap();
153        let mut st = serializer.serialize_struct("SizedVec", 1)?;
154        st.serialize_field("len", &len)?;
155        st.serialize_field("data", &self.data)?;
156        st.end()
157    }
158}
159
160impl<'de, L, T> Deserialize<'de> for PrefixedVec<L, T>
161where
162    T: Deserialize<'de>,
163    L: Deserialize<'de>,
164    L: Into<usize>,
165    L: Copy,
166{
167    #[inline]
168    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
169        #[derive(Deserialize)]
170        #[serde(field_identifier, rename_all = "lowercase")]
171        enum Field {
172            Len,
173            Data,
174        }
175
176        struct PrefixedVecVisitor<L, T> {
177            __phantom: std::marker::PhantomData<(L, T)>,
178        }
179
180        impl<'de, L, T> serde::de::Visitor<'de> for PrefixedVecVisitor<L, T>
181        where
182            T: Deserialize<'de>,
183            L: Deserialize<'de>,
184            L: Into<usize>,
185            L: Copy,
186        {
187            type Value = PrefixedVec<L, T>;
188
189            fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
190                formatter.write_str("struct PrefixedVec")
191            }
192
193            #[inline]
194            fn visit_seq<V>(self, mut seq: V) -> Result<PrefixedVec<L, T>, V::Error>
195            where
196                V: serde::de::SeqAccess<'de>,
197            {
198                // First we parse the expected size type from the wire format.
199                let len: usize = seq
200                    .next_element::<L>()?
201                    .ok_or_else(|| serde::de::Error::invalid_length(0, &"PrefixlessVec"))?
202                    .into();
203
204                // We now rely on the PrefixlessVec deserializer to do the rest of the work. We
205                // need to use the PrefixlessSeed to pass the expected size to the deserializer.
206                let data = seq
207                    .next_element_seed(PrefixlessSeed {
208                        __phantom: std::marker::PhantomData,
209                        len,
210                    })?
211                    .ok_or_else(|| serde::de::Error::invalid_length(1, &"PrefixlessVec"))?;
212
213                Ok(PrefixedVec {
214                    __phantom: std::marker::PhantomData,
215                    data,
216                })
217            }
218        }
219
220        deserializer.deserialize_struct(
221            "PrefixedVec",
222            &["len", "data"],
223            PrefixedVecVisitor {
224                __phantom: std::marker::PhantomData,
225            },
226        )
227    }
228}
229
230#[test]
231fn test_borsh_roundtrip() {
232    let prefixed_vec = PrefixedVec::<u16, u8>::from(vec![1, 2, 3, 4, 5]);
233    let encoded = borsh::to_vec(&prefixed_vec).unwrap();
234    assert_eq!(encoded, vec![5, 0, 0, 0, 1, 2, 3, 4, 5]);
235
236    let decoded_prefixed_vec = PrefixedVec::<u16, u8>::try_from_slice(encoded.as_slice()).unwrap();
237    assert_eq!(decoded_prefixed_vec, prefixed_vec);
238}