1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
use dharitri_codec::{DecodeError, EncodeError, TopDecode, TopEncode};

use crate::{
    api::{ErrorApi, ManagedTypeApi},
    err_msg,
    types::{AsManagedRef, BoxedBytes, ManagedBuffer, ManagedBytesTopDecodeInput, ManagedType},
};

pub struct ManagedSerializer<M>
where
    M: ManagedTypeApi + ErrorApi + 'static,
{
    api: M,
}

impl<M> ManagedSerializer<M>
where
    M: ManagedTypeApi + ErrorApi + 'static,
{
    pub fn new(api: M) -> Self {
        ManagedSerializer { api }
    }

    pub fn top_encode_to_managed_buffer<T: TopEncode>(&self, value: &T) -> ManagedBuffer<M> {
        let mut result = ManagedBuffer::new(self.api.clone());
        value.top_encode_or_exit(&mut result, self.api.clone(), top_encode_exit);
        result
    }

    pub fn top_encode_to_boxed_bytes<T: TopEncode>(&self, value: &T) -> BoxedBytes {
        let mut result = BoxedBytes::empty();
        value.top_encode_or_exit(&mut result, self.api.clone(), top_encode_exit);
        result
    }

    pub fn top_decode_from_managed_buffer<T: TopDecode>(&self, buffer: &ManagedBuffer<M>) -> T {
        T::top_decode_or_exit(buffer.as_managed_ref(), self.api.clone(), top_decode_exit)
    }

    pub fn top_decode_from_byte_slice<T: TopDecode>(&self, slice: &[u8]) -> T {
        let managed_input =
            ManagedBytesTopDecodeInput::new(self.api.clone(), BoxedBytes::from(slice));
        T::top_decode_or_exit(managed_input, self.api.clone(), top_decode_exit)
    }
}

#[inline(always)]
fn top_encode_exit<M>(api: M, encode_err: EncodeError) -> !
where
    M: ManagedTypeApi + ErrorApi + 'static,
{
    let mut message_buffer =
        ManagedBuffer::new_from_bytes(api.clone(), err_msg::SERIALIZER_ENCODE_ERROR);
    message_buffer.append_bytes(encode_err.message_bytes());
    api.signal_error_from_buffer(message_buffer.get_raw_handle())
}

#[inline(always)]
fn top_decode_exit<M>(api: M, decode_err: DecodeError) -> !
where
    M: ManagedTypeApi + ErrorApi + 'static,
{
    let mut message_buffer =
        ManagedBuffer::new_from_bytes(api.clone(), err_msg::SERIALIZER_DECODE_ERROR);
    message_buffer.append_bytes(decode_err.message_bytes());
    api.signal_error_from_buffer(message_buffer.get_raw_handle())
}