klever_sc_codec/single/
top_de_input.rs

1use crate::num_conv::universal_decode_number_unchecked;
2use crate::{
3    num_conv::universal_decode_number, transmute::vec_into_boxed_slice, DecodeError,
4    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    /// aligned to the right.
22    ///
23    /// This eases big endian decoding.
24    ///
25    /// Returns the length of the original buffer.
26    fn into_max_size_buffer_align_right<H, const MAX_LEN: usize>(
27        self,
28        buffer: &mut [u8; MAX_LEN],
29        h: H,
30    ) -> Result<usize, H::HandledErr>
31    where
32        H: DecodeErrorHandler;
33
34    /// Retrieves the underlying data as a pre-parsed u64.
35    /// Expected to panic if the conversion is not possible.
36    ///
37    /// Consumes the input object in the process.
38    fn into_u64<H>(self, h: H) -> Result<u64, H::HandledErr>
39    where
40        H: DecodeErrorHandler,
41    {
42        let mut buffer = [0u8; 8];
43        let _ = self.into_max_size_buffer_align_right(&mut buffer, h)?;
44        Ok(u64::from_be_bytes(buffer))
45    }
46
47    /// Retrieves the underlying data as a pre-parsed i64.
48    /// Expected to panic if the conversion is not possible.
49    ///
50    /// Consumes the input object in the process.
51    fn into_i64<H>(self, h: H) -> Result<i64, H::HandledErr>
52    where
53        H: DecodeErrorHandler,
54    {
55        let mut buffer = [0u8; 8];
56        let len = self.into_max_size_buffer_align_right(&mut buffer, h)?;
57        Ok(universal_decode_number_unchecked(&buffer[8 - len..], true) as i64)
58    }
59
60    #[inline]
61    fn supports_specialized_type<T: TryStaticCast>() -> bool {
62        false
63    }
64
65    fn into_specialized<T, H>(self, h: H) -> Result<T, H::HandledErr>
66    where
67        T: TryStaticCast,
68        H: DecodeErrorHandler,
69    {
70        Err(h.handle_error(DecodeError::UNSUPPORTED_OPERATION))
71    }
72
73    fn into_nested_buffer(self) -> Self::NestedBuffer;
74}
75
76impl TopDecodeInput for Box<[u8]> {
77    type NestedBuffer = OwnedBytesNestedDecodeInput;
78
79    fn byte_len(&self) -> usize {
80        self.len()
81    }
82
83    fn into_boxed_slice_u8(self) -> Box<[u8]> {
84        self
85    }
86
87    fn into_max_size_buffer_align_right<H, const MAX_LEN: usize>(
88        self,
89        buffer: &mut [u8; MAX_LEN],
90        h: H,
91    ) -> Result<usize, H::HandledErr>
92    where
93        H: DecodeErrorHandler,
94    {
95        (&*self).into_max_size_buffer_align_right(buffer, h)
96    }
97
98    fn into_nested_buffer(self) -> Self::NestedBuffer {
99        OwnedBytesNestedDecodeInput::new(self)
100    }
101}
102
103impl TopDecodeInput for Vec<u8> {
104    type NestedBuffer = OwnedBytesNestedDecodeInput;
105
106    fn byte_len(&self) -> usize {
107        self.len()
108    }
109
110    fn into_boxed_slice_u8(self) -> Box<[u8]> {
111        vec_into_boxed_slice(self)
112    }
113
114    fn into_max_size_buffer_align_right<H, const MAX_LEN: usize>(
115        self,
116        buffer: &mut [u8; MAX_LEN],
117        h: H,
118    ) -> Result<usize, H::HandledErr>
119    where
120        H: DecodeErrorHandler,
121    {
122        self.as_slice().into_max_size_buffer_align_right(buffer, h)
123    }
124
125    fn into_nested_buffer(self) -> Self::NestedBuffer {
126        OwnedBytesNestedDecodeInput::new(self.into_boxed_slice())
127    }
128}
129
130impl<'a> TopDecodeInput for &'a [u8] {
131    type NestedBuffer = &'a [u8];
132
133    fn byte_len(&self) -> usize {
134        self.len()
135    }
136
137    fn into_boxed_slice_u8(self) -> Box<[u8]> {
138        Box::from(self)
139    }
140
141    fn into_max_size_buffer_align_right<H, const MAX_LEN: usize>(
142        self,
143        buffer: &mut [u8; MAX_LEN],
144        h: H,
145    ) -> Result<usize, H::HandledErr>
146    where
147        H: DecodeErrorHandler,
148    {
149        let len = self.len();
150        if len > MAX_LEN {
151            return Err(h.handle_error(DecodeError::INPUT_TOO_LONG));
152        }
153        let target_start = MAX_LEN - len;
154        let byte_slice = &mut buffer[target_start..];
155        byte_slice.copy_from_slice(self);
156        Ok(len)
157    }
158
159    #[inline]
160    fn into_u64<H>(self, _h: H) -> Result<u64, H::HandledErr>
161    where
162        H: DecodeErrorHandler,
163    {
164        Ok(universal_decode_number(self, false))
165    }
166
167    #[inline]
168    fn into_i64<H>(self, _h: H) -> Result<i64, H::HandledErr>
169    where
170        H: DecodeErrorHandler,
171    {
172        Ok(universal_decode_number(self, true) as i64)
173    }
174
175    fn into_nested_buffer(self) -> Self::NestedBuffer {
176        self
177    }
178}