multiversx_sc_codec/single/
top_de_input.rs

1use crate::{
2    num_conv::{universal_decode_number, universal_decode_number_unchecked},
3    transmute::vec_into_boxed_slice,
4    DecodeError, DecodeErrorHandler, NestedDecodeInput, OwnedBytesNestedDecodeInput, TryStaticCast,
5};
6use alloc::{boxed::Box, vec::Vec};
7
8/// Trait that abstracts away an underlying API for a top-level object deserializer.
9/// The underlying API can provide pre-parsed i64/u64 or pre-bundled boxed slices.
10pub trait TopDecodeInput: Sized {
11    type NestedBuffer: NestedDecodeInput;
12
13    /// Length of the underlying data, in bytes.
14    fn byte_len(&self) -> usize;
15
16    /// Provides the underlying data as an owned byte slice box.
17    /// Consumes the input object in the process.
18    fn into_boxed_slice_u8(self) -> Box<[u8]>;
19
20    /// Puts the underlying data into a fixed size byte buffer
21    /// and returns the populated data slice from this buffer.
22    ///
23    /// Will return an error if the data exceeds the provided buffer.
24    ///
25    /// Currently only kept for backwards compatibility.
26    #[deprecated(
27        since = "0.48.1",
28        note = "Please use method `into_max_size_buffer_align_right` instead."
29    )]
30    fn into_max_size_buffer<H, const MAX_LEN: usize>(
31        self,
32        buffer: &mut [u8; MAX_LEN],
33        h: H,
34    ) -> Result<&[u8], H::HandledErr>
35    where
36        H: DecodeErrorHandler;
37
38    /// Puts the underlying data into a fixed size byte buffer,
39    /// aligned to the right.
40    ///
41    /// This eases big endian decoding.
42    ///
43    /// Returns the length of the original buffer.
44    fn into_max_size_buffer_align_right<H, const MAX_LEN: usize>(
45        self,
46        buffer: &mut [u8; MAX_LEN],
47        h: H,
48    ) -> Result<usize, H::HandledErr>
49    where
50        H: DecodeErrorHandler;
51
52    /// Retrieves the underlying data as a pre-parsed u64.
53    /// Expected to panic if the conversion is not possible.
54    ///
55    /// Consumes the input object in the process.
56    fn into_u64<H>(self, h: H) -> Result<u64, H::HandledErr>
57    where
58        H: DecodeErrorHandler,
59    {
60        let mut buffer = [0u8; 8];
61        let _ = self.into_max_size_buffer_align_right(&mut buffer, h)?;
62        Ok(u64::from_be_bytes(buffer))
63    }
64
65    /// Retrieves the underlying data as a pre-parsed i64.
66    /// Expected to panic if the conversion is not possible.
67    ///
68    /// Consumes the input object in the process.
69    fn into_i64<H>(self, h: H) -> Result<i64, H::HandledErr>
70    where
71        H: DecodeErrorHandler,
72    {
73        let mut buffer = [0u8; 8];
74        let len = self.into_max_size_buffer_align_right(&mut buffer, h)?;
75        Ok(universal_decode_number_unchecked(&buffer[8 - len..], true) as i64)
76    }
77
78    #[inline]
79    fn supports_specialized_type<T: TryStaticCast>() -> bool {
80        false
81    }
82
83    fn into_specialized<T, H>(self, h: H) -> Result<T, H::HandledErr>
84    where
85        T: TryStaticCast,
86        H: DecodeErrorHandler,
87    {
88        Err(h.handle_error(DecodeError::UNSUPPORTED_OPERATION))
89    }
90
91    fn into_nested_buffer(self) -> Self::NestedBuffer;
92}
93
94impl TopDecodeInput for Box<[u8]> {
95    type NestedBuffer = OwnedBytesNestedDecodeInput;
96
97    fn byte_len(&self) -> usize {
98        self.len()
99    }
100
101    fn into_boxed_slice_u8(self) -> Box<[u8]> {
102        self
103    }
104
105    #[allow(deprecated)]
106    fn into_max_size_buffer<H, const MAX_LEN: usize>(
107        self,
108        buffer: &mut [u8; MAX_LEN],
109        h: H,
110    ) -> Result<&[u8], H::HandledErr>
111    where
112        H: DecodeErrorHandler,
113    {
114        (&*self).into_max_size_buffer(buffer, h)
115    }
116
117    fn into_max_size_buffer_align_right<H, const MAX_LEN: usize>(
118        self,
119        buffer: &mut [u8; MAX_LEN],
120        h: H,
121    ) -> Result<usize, H::HandledErr>
122    where
123        H: DecodeErrorHandler,
124    {
125        (&*self).into_max_size_buffer_align_right(buffer, h)
126    }
127
128    fn into_nested_buffer(self) -> Self::NestedBuffer {
129        OwnedBytesNestedDecodeInput::new(self)
130    }
131}
132
133impl TopDecodeInput for Vec<u8> {
134    type NestedBuffer = OwnedBytesNestedDecodeInput;
135
136    fn byte_len(&self) -> usize {
137        self.len()
138    }
139
140    fn into_boxed_slice_u8(self) -> Box<[u8]> {
141        vec_into_boxed_slice(self)
142    }
143
144    #[allow(deprecated)]
145    fn into_max_size_buffer<H, const MAX_LEN: usize>(
146        self,
147        buffer: &mut [u8; MAX_LEN],
148        h: H,
149    ) -> Result<&[u8], H::HandledErr>
150    where
151        H: DecodeErrorHandler,
152    {
153        self.as_slice().into_max_size_buffer(buffer, h)
154    }
155
156    fn into_max_size_buffer_align_right<H, const MAX_LEN: usize>(
157        self,
158        buffer: &mut [u8; MAX_LEN],
159        h: H,
160    ) -> Result<usize, H::HandledErr>
161    where
162        H: DecodeErrorHandler,
163    {
164        self.as_slice().into_max_size_buffer_align_right(buffer, h)
165    }
166
167    fn into_nested_buffer(self) -> Self::NestedBuffer {
168        OwnedBytesNestedDecodeInput::new(self.into_boxed_slice())
169    }
170}
171
172impl<'a> TopDecodeInput for &'a [u8] {
173    type NestedBuffer = &'a [u8];
174
175    fn byte_len(&self) -> usize {
176        self.len()
177    }
178
179    fn into_boxed_slice_u8(self) -> Box<[u8]> {
180        Box::from(self)
181    }
182
183    fn into_max_size_buffer<H, const MAX_LEN: usize>(
184        self,
185        buffer: &mut [u8; MAX_LEN],
186        h: H,
187    ) -> Result<&[u8], H::HandledErr>
188    where
189        H: DecodeErrorHandler,
190    {
191        let l = self.len();
192        if l > MAX_LEN {
193            return Err(h.handle_error(DecodeError::INPUT_TOO_LONG));
194        }
195        buffer[..l].copy_from_slice(self);
196        Ok(&buffer[..l])
197    }
198
199    fn into_max_size_buffer_align_right<H, const MAX_LEN: usize>(
200        self,
201        buffer: &mut [u8; MAX_LEN],
202        h: H,
203    ) -> Result<usize, H::HandledErr>
204    where
205        H: DecodeErrorHandler,
206    {
207        let len = self.len();
208        if len > MAX_LEN {
209            return Err(h.handle_error(DecodeError::INPUT_TOO_LONG));
210        }
211        let target_start = MAX_LEN - len;
212        let byte_slice = &mut buffer[target_start..];
213        byte_slice.copy_from_slice(self);
214        Ok(len)
215    }
216
217    #[inline]
218    fn into_u64<H>(self, _h: H) -> Result<u64, H::HandledErr>
219    where
220        H: DecodeErrorHandler,
221    {
222        Ok(universal_decode_number(self, false))
223    }
224
225    #[inline]
226    fn into_i64<H>(self, _h: H) -> Result<i64, H::HandledErr>
227    where
228        H: DecodeErrorHandler,
229    {
230        Ok(universal_decode_number(self, true) as i64)
231    }
232
233    fn into_nested_buffer(self) -> Self::NestedBuffer {
234        self
235    }
236}