1use crate::rust::marker::PhantomData;
2use crate::rust::vec::Vec;
3use crate::*;
4
5#[derive(Debug, Clone, PartialEq, Eq, Sbor)]
7pub enum EncodeError {
8 MaxDepthExceeded(usize),
9 SizeTooLarge {
10 actual: usize,
11 max_allowed: usize,
12 },
13 MismatchingArrayElementValueKind {
14 element_value_kind: u8,
15 actual_value_kind: u8,
16 },
17 MismatchingMapKeyValueKind {
18 key_value_kind: u8,
19 actual_value_kind: u8,
20 },
21 MismatchingMapValueValueKind {
22 value_value_kind: u8,
23 actual_value_kind: u8,
24 },
25}
26
27pub trait Encoder<X: CustomValueKind>: Sized {
28 #[inline]
33 fn encode_payload<T: Encode<X, Self> + ?Sized>(
34 mut self,
35 value: &T,
36 payload_prefix: u8,
37 ) -> Result<(), EncodeError> {
38 self.write_payload_prefix(payload_prefix)?;
39 self.encode(value)
40 }
41
42 fn encode<T: Encode<X, Self> + ?Sized>(&mut self, value: &T) -> Result<(), EncodeError> {
46 value.encode_value_kind(self)?;
47 self.encode_deeper_body(value)
48 }
49
50 fn encode_deeper_body<T: Encode<X, Self> + ?Sized>(
75 &mut self,
76 value: &T,
77 ) -> Result<(), EncodeError>;
78
79 #[inline]
80 fn write_payload_prefix(&mut self, payload_prefix: u8) -> Result<(), EncodeError> {
81 self.write_byte(payload_prefix)
82 }
83
84 #[inline]
85 fn write_value_kind(&mut self, ty: ValueKind<X>) -> Result<(), EncodeError> {
86 self.write_byte(ty.as_u8())
87 }
88
89 #[inline]
90 fn write_discriminator(&mut self, discriminator: u8) -> Result<(), EncodeError> {
91 self.write_byte(discriminator)
92 }
93
94 fn write_size(&mut self, mut size: usize) -> Result<(), EncodeError> {
95 if size > 0x0FFFFFFF {
98 return Err(EncodeError::SizeTooLarge {
99 actual: size,
100 max_allowed: 0x0FFFFFFF,
101 });
102 }
103 loop {
104 let seven_bits = size & 0x7F;
105 size >>= 7;
106 if size == 0 {
107 self.write_byte(seven_bits as u8)?;
108 break;
109 } else {
110 self.write_byte(seven_bits as u8 | 0x80)?;
111 }
112 }
113 Ok(())
114 }
115
116 fn write_byte(&mut self, n: u8) -> Result<(), EncodeError>;
117
118 fn write_slice(&mut self, slice: &[u8]) -> Result<(), EncodeError>;
119}
120
121pub struct VecEncoder<'a, X: CustomValueKind> {
123 buf: &'a mut Vec<u8>,
124 max_depth: usize,
125 stack_depth: usize,
126 phantom: PhantomData<X>,
127}
128
129impl<'a, X: CustomValueKind> VecEncoder<'a, X> {
130 pub fn new(buf: &'a mut Vec<u8>, max_depth: usize) -> Self {
131 Self {
132 buf,
133 stack_depth: 0,
134 max_depth,
135 phantom: PhantomData,
136 }
137 }
138
139 #[inline]
140 fn track_stack_depth_increase(&mut self) -> Result<(), EncodeError> {
141 self.stack_depth += 1;
142 if self.stack_depth > self.max_depth {
143 return Err(EncodeError::MaxDepthExceeded(self.max_depth));
144 }
145 Ok(())
146 }
147
148 #[inline]
149 fn track_stack_depth_decrease(&mut self) -> Result<(), EncodeError> {
150 self.stack_depth -= 1;
151 Ok(())
152 }
153}
154
155impl<'a, X: CustomValueKind> Encoder<X> for VecEncoder<'a, X> {
156 fn encode_deeper_body<T: Encode<X, Self> + ?Sized>(
157 &mut self,
158 value: &T,
159 ) -> Result<(), EncodeError> {
160 self.track_stack_depth_increase()?;
161 value.encode_body(self)?;
162 self.track_stack_depth_decrease()
163 }
164
165 #[inline]
166 fn write_byte(&mut self, n: u8) -> Result<(), EncodeError> {
167 self.buf.push(n);
168 Ok(())
169 }
170
171 #[inline]
172 fn write_slice(&mut self, slice: &[u8]) -> Result<(), EncodeError> {
173 self.buf.extend(slice);
174 Ok(())
175 }
176}
177
178#[cfg(test)]
179mod tests {
180 use super::*;
181 use crate::internal_prelude::*;
182
183 fn do_encoding(encoder: &mut BasicEncoder) -> Result<(), EncodeError> {
184 encoder.encode(&())?;
185 encoder.encode(&true)?;
186 encoder.encode(&1i8)?;
187 encoder.encode(&1i16)?;
188 encoder.encode(&1i32)?;
189 encoder.encode(&1i64)?;
190 encoder.encode(&1i128)?;
191 encoder.encode(&1u8)?;
192 encoder.encode(&1u16)?;
193 encoder.encode(&1u32)?;
194 encoder.encode(&1u64)?;
195 encoder.encode(&1u128)?;
196 encoder.encode("hello")?;
197
198 encoder.encode(&[1u32, 2u32, 3u32])?;
199 encoder.encode(&(1u32, 2u32))?;
200
201 encoder.encode(&vec![1u32, 2u32, 3u32])?;
202 let mut set = BTreeSet::<u8>::new();
203 set.insert(1);
204 set.insert(2);
205 encoder.encode(&set)?;
206 let mut map = BTreeMap::<u8, u8>::new();
207 map.insert(1, 2);
208 map.insert(3, 4);
209 encoder.encode(&map)?;
210
211 encoder.encode(&Option::<u32>::None)?;
212 encoder.encode(&Some(1u32))?;
213 encoder.encode(&Result::<u32, String>::Ok(1u32))?;
214 encoder.encode(&Result::<u32, String>::Err("hello".to_owned()))?;
215
216 Ok(())
217 }
218
219 #[test]
220 pub fn test_encoding() {
221 let mut bytes = Vec::with_capacity(512);
222 let mut enc = BasicEncoder::new(&mut bytes, 256);
223 do_encoding(&mut enc).unwrap();
224
225 assert_eq!(
226 vec![
227 33, 0, 1, 1, 2, 1, 3, 1, 0, 4, 1, 0, 0, 0, 5, 1, 0, 0, 0, 0, 0, 0, 0, 6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 1, 8, 1, 0, 9, 1, 0, 0, 0, 10, 1, 0, 0, 0, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 5, 104, 101, 108, 108, 111, 32, 9, 3, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 33, 2, 9, 1, 0, 0, 0, 9, 2, 0, 0, 0, 32, 9, 3, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 32, 7, 2, 1, 2, 35, 7, 7, 2, 1, 2, 3, 4, 34, 0, 0, 34, 1, 1, 9, 1, 0, 0, 0, 34, 0, 1, 9, 1, 0, 0, 0, 34, 1, 1, 12, 5, 104, 101, 108, 108, 111, ],
250 bytes
251 );
252 }
253
254 #[test]
255 pub fn test_size_too_large_error() {
256 const MAX_SIZE: usize = 0x0FFFFFFF; const TOO_LARGE_SIZE: usize = MAX_SIZE + 1;
258
259 assert!(basic_encode(&vec![0u8; MAX_SIZE]).is_ok());
260 assert_matches!(
261 basic_encode(&vec![0u8; MAX_SIZE + 1]),
262 Err(EncodeError::SizeTooLarge {
263 actual: TOO_LARGE_SIZE,
264 max_allowed: MAX_SIZE
265 })
266 );
267 }
268
269 #[test]
270 pub fn test_encode_index_map_and_set() {
271 let mut bytes = Vec::with_capacity(512);
272 let mut encoder = BasicEncoder::new(&mut bytes, 256);
273 let mut set = index_set_new::<u8>();
274 set.insert(1);
275 set.insert(2);
276 encoder.encode(&set).unwrap();
277 let mut map = index_map_new::<u8, u8>();
278 map.insert(1, 2);
279 map.insert(3, 4);
280 encoder.encode(&map).unwrap();
281
282 assert_eq!(
283 vec![
284 32, 7, 2, 1, 2, 35, 7, 7, 2, 1, 2, 3, 4, ],
287 bytes
288 );
289
290 let mut decoder = BasicDecoder::new(&bytes, 256);
291 let set_out = decoder.decode::<IndexSet<u8>>().unwrap();
292 let map_out = decoder.decode::<IndexMap<u8, u8>>().unwrap();
293 decoder.check_end().unwrap();
294
295 assert_eq!(set, set_out);
296 assert_eq!(map, map_out);
297 }
298
299 #[test]
300 pub fn test_encode_cow_borrowed() {
301 let mut set = BTreeSet::<u8>::new();
302 set.insert(1);
303 set.insert(2);
304 let x = crate::rust::borrow::Cow::Borrowed(&set);
305 let mut bytes = Vec::with_capacity(512);
306 let mut encoder = BasicEncoder::new(&mut bytes, 256);
307 encoder.encode(&x).unwrap();
308 assert_eq!(bytes, vec![32, 7, 2, 1, 2]) }
310
311 #[test]
312 pub fn test_encode_cow_owned() {
313 use crate::rust::borrow::Cow;
314 let x: Cow<u8> = Cow::Owned(5u8);
315 let mut bytes = Vec::with_capacity(512);
316 let mut encoder = BasicEncoder::new(&mut bytes, 256);
317 encoder.encode(&x).unwrap();
318 assert_eq!(bytes, vec![7, 5])
319 }
320
321 #[test]
322 pub fn test_encode_box() {
323 let x = Box::new(5u8);
324 let mut bytes = Vec::with_capacity(512);
325 let mut encoder = BasicEncoder::new(&mut bytes, 256);
326 encoder.encode(&x).unwrap();
327 assert_eq!(bytes, vec![7, 5])
328 }
329
330 #[test]
331 pub fn test_encode_rc() {
332 let x = crate::rust::rc::Rc::new(5u8);
333 let mut bytes = Vec::with_capacity(512);
334 let mut encoder = BasicEncoder::new(&mut bytes, 256);
335 encoder.encode(&x).unwrap();
336 assert_eq!(bytes, vec![7, 5])
337 }
338
339 #[test]
340 pub fn test_encode_ref_cell() {
341 let x = crate::rust::cell::RefCell::new(5u8);
342 let mut bytes = Vec::with_capacity(512);
343 let mut encoder = BasicEncoder::new(&mut bytes, 256);
344 encoder.encode(&x).unwrap();
345 assert_eq!(bytes, vec![7, 5])
346 }
347}