pythnet_sdk/wire/
prefixed_vec.rs

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