risc0_zeroio/
deserialize.rs1use alloc::{boxed::Box, vec::Vec};
16use core::marker::PhantomData;
17
18use impl_trait_for_tuples::impl_for_tuples;
19
20use super::align_bytes_to_words;
21
22pub trait Deserialize<'a> {
23 type RefType;
24
25 const FIXED_WORDS: usize;
26
27 fn deserialize_from(words: &'a [u32]) -> Self::RefType;
28
29 fn from_ref(val: &Self::RefType) -> Self;
30}
31
32pub trait DeserializeOwned: for<'a> Deserialize<'a> {}
33impl<T> DeserializeOwned for T where T: for<'a> Deserialize<'a> {}
34
35impl<'a> Deserialize<'a> for u32 {
36 type RefType = u32;
37
38 const FIXED_WORDS: usize = 1;
39
40 fn deserialize_from(words: &[u32]) -> Self::RefType {
41 words[0]
42 }
43
44 fn from_ref(val: &Self::RefType) -> Self {
45 *val
46 }
47}
48
49impl<'a> Deserialize<'a> for alloc::string::String {
50 type RefType = &'a str;
51
52 const FIXED_WORDS: usize = 2;
53
54 fn deserialize_from(words: &'a [u32]) -> Self::RefType {
55 let (len, ptr) = (words[0], words[1]);
56
57 core::str::from_utf8(&bytemuck::cast_slice(&words[ptr as usize..])[..len as usize]).unwrap()
58 }
59
60 fn from_ref(val: &Self::RefType) -> Self {
61 (*val).into()
62 }
63}
64
65impl<'a> Deserialize<'a> for Vec<u8> {
66 type RefType = &'a [u8];
67
68 const FIXED_WORDS: usize = 2;
69
70 fn deserialize_from(words: &'a [u32]) -> Self::RefType {
71 let (len, ptr) = (words[0], words[1]);
72
73 &bytemuck::cast_slice(&words[ptr as usize..])[..len as usize]
74 }
75
76 fn from_ref(val: &Self::RefType) -> Self {
77 (*val).into()
78 }
79}
80
81impl<'a, T: Deserialize<'a>> Deserialize<'a> for Option<T> {
82 type RefType = Option<T::RefType>;
83
84 const FIXED_WORDS: usize = 1;
85
86 fn deserialize_from(words: &'a [u32]) -> Self::RefType {
87 let ptr = words[0];
88
89 if ptr == 0 {
90 None
91 } else {
92 Some(T::deserialize_from(&words[ptr as usize..]))
93 }
94 }
95
96 fn from_ref(val: &Self::RefType) -> Self {
97 val.as_ref().map(|v| T::from_ref(&v))
98 }
99}
100
101impl<'a, T: Deserialize<'a>> Deserialize<'a> for Box<T> {
102 type RefType = T::RefType;
103
104 const FIXED_WORDS: usize = T::FIXED_WORDS;
105
106 fn deserialize_from(words: &'a [u32]) -> T::RefType {
107 T::deserialize_from(words)
108 }
109
110 fn from_ref(val: &Self::RefType) -> Self {
111 Box::new(T::from_ref(&val))
112 }
113}
114
115pub struct VecRef<'a, T> {
116 len: usize,
117 words: &'a [u32],
118 phantom: PhantomData<T>,
119}
120
121impl<'a, T: Deserialize<'a>> VecRef<'a, T> {
122 pub fn len(&self) -> usize {
123 self.len
124 }
125
126 pub fn index(&self, index: usize) -> T::RefType {
127 T::deserialize_from(&self.words[T::FIXED_WORDS * index..])
128 }
129
130 pub fn as_u32s(&self) -> &'a [u32] {
131 &self.words[..T::FIXED_WORDS * self.len]
132 }
133}
134
135pub struct VecRefIter<'a, T> {
136 words: &'a [u32],
137 items_left: usize,
138 phantom: PhantomData<T>,
139}
140
141impl<'a, T: Deserialize<'a>> VecRef<'a, T> {
142 pub fn iter(&self) -> VecRefIter<'a, T> {
143 VecRefIter {
144 words: self.words,
145 items_left: self.len,
146 phantom: PhantomData,
147 }
148 }
149}
150
151impl<'a, T: Deserialize<'a>> IntoIterator for VecRef<'a, T> {
152 type Item = T::RefType;
153 type IntoIter = VecRefIter<'a, T>;
154
155 fn into_iter(self) -> Self::IntoIter {
156 self.iter()
157 }
158}
159
160impl<'a, T: Deserialize<'a>> Iterator for VecRefIter<'a, T> {
161 type Item = T::RefType;
162 fn next(&mut self) -> Option<T::RefType> {
163 if self.items_left > 0 {
164 let val = T::deserialize_from(self.words);
165 self.items_left -= 1;
166 self.words = &self.words[T::FIXED_WORDS..];
167 Some(val)
168 } else {
169 None
170 }
171 }
172}
173
174impl<'a, T: Deserialize<'a>> Deserialize<'a> for Vec<T> {
175 type RefType = VecRef<'a, T>;
176
177 const FIXED_WORDS: usize = 2;
178
179 fn deserialize_from(words: &'a [u32]) -> Self::RefType {
180 VecRef {
181 len: words[0] as usize,
182 words: &words[words[1] as usize..],
183 phantom: PhantomData,
184 }
185 }
186
187 fn from_ref(val: &Self::RefType) -> Self {
188 let mut v = Vec::with_capacity(val.len());
189 v.extend(val.iter().map(|v| T::from_ref(&v)));
190 v
191 }
192}
193
194impl<'a, T: Deserialize<'a>, const N: usize> Deserialize<'a> for [T; N] {
195 type RefType = VecRef<'a, T>;
196
197 const FIXED_WORDS: usize = N * T::FIXED_WORDS;
198
199 fn deserialize_from(words: &'a [u32]) -> Self::RefType {
200 VecRef {
201 len: N,
202 words,
203 phantom: PhantomData,
204 }
205 }
206
207 fn from_ref(val: &Self::RefType) -> Self {
208 match Vec::from_iter(val.iter().map(|x| T::from_ref(&x))).try_into() {
209 Ok(result) => result,
210 _ => panic!("VecRef iterator didn't return the proper number of elements"),
211 }
212 }
213}
214
215impl<'a, const N: usize> Deserialize<'a> for [u8; N] {
216 type RefType = &'a [u8; N];
217
218 const FIXED_WORDS: usize = align_bytes_to_words(N);
219
220 fn deserialize_from(words: &'a [u32]) -> Self::RefType {
221 let slice = &bytemuck::cast_slice(words)[..N];
222 slice.try_into().unwrap()
223 }
224
225 fn from_ref(val: &Self::RefType) -> Self {
226 **val
227 }
228}
229
230#[impl_for_tuples(1, 5)]
231impl<'a> Deserialize<'a> for Tuple {
232 for_tuples!(type RefType = (#(Tuple::RefType),*););
233 for_tuples!(const FIXED_WORDS: usize = #(Tuple::FIXED_WORDS)+*; );
234
235 fn deserialize_from(words: &'a [u32]) -> Self::RefType {
236 let mut pos = 0;
237 let mut inc_pos = |n| {
238 let old_pos = pos;
239 pos += n;
240 old_pos
241 };
242 for_tuples!(
243 (#(
244 Tuple::deserialize_from(&words[inc_pos(Tuple::FIXED_WORDS)..])
245 ),*));
246 }
247
248 fn from_ref(val: &Self::RefType) -> Self {
249 for_tuples!(
250 (#(
251 Tuple::from_ref(&val.Tuple)
252 ),*));
253 }
254}
255
256impl<'a> Deserialize<'a> for () {
257 type RefType = ();
258 const FIXED_WORDS: usize = 0;
259
260 fn deserialize_from(_words: &'a [u32]) -> Self::RefType {
261 ()
262 }
263
264 fn from_ref(_val: &Self::RefType) -> Self {
265 ()
266 }
267}