Skip to main content

sbor/
encoder.rs

1use crate::rust::marker::PhantomData;
2use crate::rust::vec::Vec;
3use crate::*;
4
5/// Represents an error occurred during encoding.
6#[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    /// Consumes the Encoder and encodes the value as a full payload
29    ///
30    /// It starts by writing the payload prefix: It's the intention that each version of SBOR
31    /// or change to the custom codecs should be given its own prefix
32    #[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    /// Encodes the value as part of a larger payload
43    ///
44    /// This method encodes the SBOR value's kind and then its body.
45    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    /// Encodes the SBOR body of a child value as part of a larger payload.
51    ///
52    /// In many cases, you may wish to directly call `value.encode_body` instead of this method. See
53    /// the below section for details.
54    ///
55    /// ## Direct calls and SBOR Depth
56    ///
57    /// In order to avoid SBOR depth differentials and disagreement about whether a payload
58    /// is valid, typed codec implementations should ensure that the SBOR depth as measured
59    /// during the encoding/decoding process agrees with the Value codec.
60    ///
61    /// Each layer of the Value counts as one depth.
62    ///
63    /// If the encoder you're writing is embedding a child type (and is represented as such
64    /// in the Value type), then you should call `encoder.encode_deeper_body` to increment
65    /// the SBOR depth tracker.
66    ///
67    /// You should call `value.encode_body` directly when the encoding of that type
68    /// into an Value doesn't increase the SBOR depth in the encoder, that is:
69    /// * When the wrapping type is invisible to the Value, ie:
70    ///   * Smart pointers
71    ///   * Transparent wrappers
72    /// * Where the use of the inner type is invisible to Value, ie:
73    ///   * Where the use of `value.encode_body` is coincidental / code re-use
74    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        // LEB128 and 4 bytes max
96        // This means the max size is 0x0FFFFFFF = 268,435,455
97        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
121/// An `Encoder` abstracts the logic for writing core types into a byte buffer.
122pub 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, // unit (encoded as empty tuple)
228                1, 1, // bool
229                2, 1, // i8
230                3, 1, 0, // i16
231                4, 1, 0, 0, 0, // i32
232                5, 1, 0, 0, 0, 0, 0, 0, 0, // i64
233                6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // i128
234                7, 1, // u8
235                8, 1, 0, // u16
236                9, 1, 0, 0, 0, // u32
237                10, 1, 0, 0, 0, 0, 0, 0, 0, // u64
238                11, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // u128
239                12, 5, 104, 101, 108, 108, 111, // string
240                32, 9, 3, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, // array
241                33, 2, 9, 1, 0, 0, 0, 9, 2, 0, 0, 0, // tuple
242                32, 9, 3, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, // vec
243                32, 7, 2, 1, 2, // set
244                35, 7, 7, 2, 1, 2, 3, 4, // map
245                34, 0, 0, // None
246                34, 1, 1, 9, 1, 0, 0, 0, // Some<T>
247                34, 0, 1, 9, 1, 0, 0, 0, // Ok<T>
248                34, 1, 1, 12, 5, 104, 101, 108, 108, 111, // Err<T>
249            ],
250            bytes
251        );
252    }
253
254    #[test]
255    pub fn test_size_too_large_error() {
256        const MAX_SIZE: usize = 0x0FFFFFFF; // 268,435,455, so this many bytes is about 268MB
257        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, // set
285                35, 7, 7, 2, 1, 2, 3, 4, // map
286            ],
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]) // Same as set above
309    }
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}