multiversx_sc/contract_base/wrappers/
serializer.rs1use core::{convert::Infallible, marker::PhantomData};
2
3use unwrap_infallible::UnwrapInfallible;
4
5use crate::codec::{
6 DecodeError, DecodeErrorHandler, EncodeError, EncodeErrorHandler, TopDecode, TopEncode,
7};
8
9use crate::{
10 api::{ErrorApi, ErrorApiImpl, ManagedTypeApi},
11 err_msg,
12 types::{ManagedBuffer, ManagedType, heap::BoxedBytes},
13};
14
15#[derive(Default)]
16pub struct ManagedSerializer<M>
17where
18 M: ManagedTypeApi + ErrorApi + 'static,
19{
20 _phantom: PhantomData<M>,
21}
22
23impl<M> ManagedSerializer<M>
24where
25 M: ManagedTypeApi + ErrorApi + 'static,
26{
27 pub fn new() -> Self {
28 ManagedSerializer {
29 _phantom: PhantomData,
30 }
31 }
32
33 pub fn top_encode_to_managed_buffer<T: TopEncode>(&self, value: &T) -> ManagedBuffer<M> {
34 let mut result = ManagedBuffer::new();
35 value
36 .top_encode_or_handle_err(
37 &mut result,
38 ExitCodecErrorHandler::<M>::from(err_msg::SERIALIZER_ENCODE_ERROR),
39 )
40 .unwrap_infallible();
41 result
42 }
43
44 pub fn top_encode_to_boxed_bytes<T: TopEncode>(&self, value: &T) -> BoxedBytes {
45 let mut result = BoxedBytes::empty();
46 value
47 .top_encode_or_handle_err(
48 &mut result,
49 ExitCodecErrorHandler::<M>::from(err_msg::SERIALIZER_ENCODE_ERROR),
50 )
51 .unwrap_infallible();
52 result
53 }
54
55 pub fn top_decode_from_managed_buffer<T: TopDecode>(&self, buffer: &ManagedBuffer<M>) -> T {
56 self.top_decode_from_managed_buffer_custom_message(buffer, err_msg::SERIALIZER_DECODE_ERROR)
57 }
58
59 pub fn top_decode_from_managed_buffer_custom_message<T: TopDecode>(
60 &self,
61 buffer: &ManagedBuffer<M>,
62 error_message: &'static str,
63 ) -> T {
64 T::top_decode_or_handle_err(
65 buffer.clone(), ExitCodecErrorHandler::<M>::from(error_message),
67 )
68 .unwrap_infallible()
69 }
70
71 pub fn top_decode_from_byte_slice<T: TopDecode>(&self, slice: &[u8]) -> T {
72 T::top_decode_or_handle_err(
73 slice,
74 ExitCodecErrorHandler::<M>::from(err_msg::SERIALIZER_DECODE_ERROR),
75 )
76 .unwrap_infallible()
77 }
78}
79
80#[derive(Clone)]
81pub struct ExitCodecErrorHandler<M>
82where
83 M: ManagedTypeApi + ErrorApi,
84{
85 _phantom: PhantomData<M>,
86 pub base_message: &'static str,
87}
88
89impl<M> Copy for ExitCodecErrorHandler<M> where M: ManagedTypeApi + ErrorApi {}
90
91impl<M> From<&'static str> for ExitCodecErrorHandler<M>
92where
93 M: ManagedTypeApi + ErrorApi,
94{
95 fn from(base_message: &'static str) -> Self {
96 ExitCodecErrorHandler {
97 _phantom: PhantomData,
98 base_message,
99 }
100 }
101}
102
103impl<M> EncodeErrorHandler for ExitCodecErrorHandler<M>
104where
105 M: ManagedTypeApi + ErrorApi,
106{
107 type HandledErr = Infallible;
108
109 fn handle_error(&self, err: EncodeError) -> Self::HandledErr {
110 let mut message_buffer = ManagedBuffer::<M>::new_from_bytes(self.base_message.as_bytes());
111 message_buffer.append_bytes(err.message_bytes());
112 M::error_api_impl().signal_error_from_buffer(message_buffer.get_handle())
113 }
114}
115
116impl<M> DecodeErrorHandler for ExitCodecErrorHandler<M>
117where
118 M: ManagedTypeApi + ErrorApi,
119{
120 type HandledErr = Infallible;
121
122 fn handle_error(&self, err: DecodeError) -> Self::HandledErr {
123 let mut message_buffer = ManagedBuffer::<M>::new_from_bytes(self.base_message.as_bytes());
124 message_buffer.append_bytes(err.message_bytes());
125 M::error_api_impl().signal_error_from_buffer(message_buffer.get_handle())
126 }
127}