Skip to main content

wry_bindgen/encode/
containers.rs

1//! Container, result, and slice binary protocol implementations.
2
3use alloc::boxed::Box;
4use alloc::vec::Vec;
5
6use crate::ipc::{DecodeError, DecodedData, EncodedData};
7
8use super::{BatchableResult, BinaryDecode, BinaryEncode, EncodeTypeDef, TypeTag};
9
10impl<T: EncodeTypeDef> EncodeTypeDef for Option<T> {
11    fn encode_type_def(buf: &mut Vec<u8>) {
12        // Option encodes as: [Option tag] [inner type]
13        // Actual values encode as: [u8 flag (0=None, 1=Some)] [value if Some]
14        buf.push(TypeTag::Option as u8);
15        T::encode_type_def(buf);
16    }
17}
18
19impl<T: BinaryDecode> BinaryDecode for Option<T> {
20    fn decode(decoder: &mut DecodedData) -> Result<Self, DecodeError> {
21        let has_value = decoder.take_u8()? != 0;
22        if has_value {
23            Ok(Some(T::decode(decoder)?))
24        } else {
25            Ok(None)
26        }
27    }
28}
29
30// Encoding for Option<T> where T is encodable
31impl<T: BinaryEncode<P>, P> BinaryEncode<P> for Option<T> {
32    fn encode(self, encoder: &mut EncodedData) {
33        match self {
34            Some(val) => {
35                encoder.push_u8(1);
36                val.encode(encoder);
37            }
38            None => {
39                encoder.push_u8(0);
40            }
41        }
42    }
43}
44
45impl<T: BinaryDecode> BatchableResult for Option<T> {}
46
47impl<T: EncodeTypeDef, E: EncodeTypeDef> EncodeTypeDef for Result<T, E> {
48    fn encode_type_def(buf: &mut Vec<u8>) {
49        // Result encodes as: [Result tag] [ok type] [err type]
50        buf.push(TypeTag::Result as u8);
51        T::encode_type_def(buf);
52        E::encode_type_def(buf);
53    }
54}
55
56impl<T: BinaryEncode, E: BinaryEncode> BinaryEncode for Result<T, E> {
57    fn encode(self, encoder: &mut EncodedData) {
58        match self {
59            Ok(value) => {
60                encoder.push_u8(1);
61                value.encode(encoder);
62            }
63            Err(error) => {
64                encoder.push_u8(0);
65                error.encode(encoder);
66            }
67        }
68    }
69}
70
71impl<T: BinaryDecode, E: BinaryDecode> BinaryDecode for Result<T, E> {
72    fn decode(decoder: &mut DecodedData) -> Result<Self, DecodeError> {
73        let is_ok = decoder.take_u8()? != 0;
74        if is_ok {
75            Ok(Ok(T::decode(decoder)?))
76        } else {
77            Ok(Err(E::decode(decoder)?))
78        }
79    }
80}
81
82impl<T: BinaryDecode, E: BinaryDecode> BatchableResult for Result<T, E> {}
83
84impl<T: EncodeTypeDef> EncodeTypeDef for Vec<T> {
85    fn encode_type_def(buf: &mut Vec<u8>) {
86        // Array type tag followed by element type
87        buf.push(TypeTag::Array as u8);
88        T::encode_type_def(buf);
89    }
90}
91
92impl<T: EncodeTypeDef> EncodeTypeDef for &[T] {
93    fn encode_type_def(buf: &mut Vec<u8>) {
94        // Array type tag followed by element type
95        buf.push(TypeTag::Array as u8);
96        T::encode_type_def(buf);
97    }
98}
99
100impl<T: EncodeTypeDef> EncodeTypeDef for &mut [T] {
101    fn encode_type_def(buf: &mut Vec<u8>) {
102        // Array type tag followed by element type
103        buf.push(TypeTag::Array as u8);
104        T::encode_type_def(buf);
105    }
106}
107
108impl<T: EncodeTypeDef> EncodeTypeDef for Box<[T]> {
109    fn encode_type_def(buf: &mut Vec<u8>) {
110        // Array type tag followed by element type
111        buf.push(TypeTag::Array as u8);
112        T::encode_type_def(buf);
113    }
114}
115
116impl<T: BinaryEncode> BinaryEncode for Box<[T]> {
117    fn encode(self, encoder: &mut EncodedData) {
118        encoder.push_u32(self.len() as u32);
119        for val in self.into_vec() {
120            val.encode(encoder);
121        }
122    }
123}
124
125impl<T: BinaryEncode> BinaryEncode for Vec<T> {
126    fn encode(self, encoder: &mut EncodedData) {
127        encoder.push_u32(self.len() as u32);
128        for val in self {
129            val.encode(encoder);
130        }
131    }
132}
133
134impl<T: BinaryDecode> BinaryDecode for Vec<T> {
135    fn decode(decoder: &mut DecodedData) -> Result<Self, DecodeError> {
136        let len = decoder.take_u32()? as usize;
137        let mut vec = Vec::with_capacity(len);
138        for _ in 0..len {
139            vec.push(T::decode(decoder)?);
140        }
141        Ok(vec)
142    }
143}
144
145impl<T: BinaryDecode> BatchableResult for Vec<T> {}
146
147macro_rules! impl_jsgeneric_slice_encode {
148    ($($slice:ty),* $(,)?) => {
149        $(
150            impl<T> BinaryEncode for $slice
151            where
152                T: crate::convert::JsGeneric,
153            {
154                fn encode(self, encoder: &mut EncodedData) {
155                    encoder.push_u32(self.len() as u32);
156                    for val in self {
157                        encoder.push_u64(val.as_ref().id());
158                    }
159                }
160            }
161        )*
162    };
163}
164
165impl_jsgeneric_slice_encode!(&[T], &mut [T]);