testnumbat_wasm/types/managed/
managed_vec_item.rs

1use crate::{
2    api::{Handle, ManagedTypeApi},
3    types::TokenIdentifier,
4};
5
6use super::{
7    BigInt, BigUint, EllipticCurve, ManagedAddress, ManagedBuffer, ManagedType, ManagedVec,
8};
9
10/// Types that implement this trait can be items inside a `ManagedVec`.
11/// All these types need a payload, i.e a representation that gets stored
12/// in the underlying managed buffer.
13/// Not all data needs to be stored as payload, for instance for most managed types
14/// the payload is just the handle, whereas the mai ndata is kept by the VM.
15pub trait ManagedVecItem<M: ManagedTypeApi> {
16    /// Size of the data stored in the underlying `ManagedBuffer`.
17    const PAYLOAD_SIZE: usize;
18
19    /// If false, then the encoding of the item is identical to the payload,
20    /// and no further conversion is necessary
21    /// (the underlying buffer can be used as-is during serialization).
22    /// True for all managed types, but false for basic types (like `u32`).
23    const NEEDS_RESERIALIZATION: bool;
24
25    fn from_byte_reader<Reader: FnMut(&mut [u8])>(api: M, reader: Reader) -> Self;
26
27    fn to_byte_writer<R, Writer: FnMut(&[u8]) -> R>(&self, writer: Writer) -> R;
28}
29
30macro_rules! impl_int {
31    ($ty:ident, $payload_size:expr) => {
32        impl<M: ManagedTypeApi> ManagedVecItem<M> for $ty {
33            const PAYLOAD_SIZE: usize = $payload_size;
34            const NEEDS_RESERIALIZATION: bool = false;
35
36            fn from_byte_reader<Reader: FnMut(&mut [u8])>(_api: M, mut reader: Reader) -> Self {
37                let mut arr: [u8; $payload_size] = [0u8; $payload_size];
38                reader(&mut arr[..]);
39                $ty::from_be_bytes(arr)
40            }
41
42            fn to_byte_writer<R, Writer: FnMut(&[u8]) -> R>(&self, mut writer: Writer) -> R {
43                let bytes = self.to_be_bytes();
44                writer(&bytes)
45            }
46        }
47    };
48}
49
50impl_int! {u32, 4}
51impl_int! {i32, 4}
52
53impl<M: ManagedTypeApi> ManagedVecItem<M> for usize {
54    const PAYLOAD_SIZE: usize = 4;
55    const NEEDS_RESERIALIZATION: bool = false;
56
57    fn from_byte_reader<Reader: FnMut(&mut [u8])>(_api: M, mut reader: Reader) -> Self {
58        let mut arr: [u8; 4] = [0u8; 4];
59        reader(&mut arr[..]);
60        u32::from_be_bytes(arr) as usize
61    }
62
63    fn to_byte_writer<R, Writer: FnMut(&[u8]) -> R>(&self, mut writer: Writer) -> R {
64        let bytes = (*self as u32).to_be_bytes();
65        writer(&bytes)
66    }
67}
68
69macro_rules! impl_managed_type {
70    ($ty:ident) => {
71        impl<M: ManagedTypeApi> ManagedVecItem<M> for $ty<M> {
72            const PAYLOAD_SIZE: usize = 4;
73            const NEEDS_RESERIALIZATION: bool = true;
74
75            fn from_byte_reader<Reader: FnMut(&mut [u8])>(api: M, reader: Reader) -> Self {
76                let handle = Handle::from_byte_reader(api.clone(), reader);
77                $ty::from_raw_handle(api, handle)
78            }
79
80            fn to_byte_writer<R, Writer: FnMut(&[u8]) -> R>(&self, writer: Writer) -> R {
81                <Handle as ManagedVecItem<M>>::to_byte_writer(&self.get_raw_handle(), writer)
82            }
83        }
84    };
85}
86
87impl_managed_type! {ManagedBuffer}
88impl_managed_type! {BigUint}
89impl_managed_type! {BigInt}
90impl_managed_type! {EllipticCurve}
91impl_managed_type! {ManagedAddress}
92impl_managed_type! {TokenIdentifier}
93
94impl<M, T> ManagedVecItem<M> for ManagedVec<M, T>
95where
96    M: ManagedTypeApi,
97    T: ManagedVecItem<M>,
98{
99    const PAYLOAD_SIZE: usize = 4;
100    const NEEDS_RESERIALIZATION: bool = true;
101
102    fn from_byte_reader<Reader: FnMut(&mut [u8])>(api: M, reader: Reader) -> Self {
103        let handle = Handle::from_byte_reader(api.clone(), reader);
104        Self::from_raw_handle(api, handle)
105    }
106
107    fn to_byte_writer<R, Writer: FnMut(&[u8]) -> R>(&self, writer: Writer) -> R {
108        <Handle as ManagedVecItem<M>>::to_byte_writer(&self.get_raw_handle(), writer)
109    }
110}