aldrin_core/message/
call_function_reply.rs

1use super::message_ops::Sealed;
2use super::{Message, MessageKind, MessageOps};
3use crate::error::SerializeError;
4use crate::message_deserializer::{MessageDeserializeError, MessageWithValueDeserializer};
5use crate::message_serializer::{MessageSerializeError, MessageSerializer};
6use crate::serialized_value::{SerializedValue, SerializedValueSlice};
7use crate::value_serializer::Serialize;
8use bytes::BytesMut;
9use num_enum::{IntoPrimitive, TryFromPrimitive};
10
11#[derive(Debug, Copy, Clone, PartialEq, Eq, IntoPrimitive, TryFromPrimitive)]
12#[repr(u8)]
13enum CallFunctionReplyKind {
14    Ok = 0,
15    Err = 1,
16    Aborted = 2,
17    InvalidService = 3,
18    InvalidFunction = 4,
19    InvalidArgs = 5,
20}
21
22#[derive(Debug, Clone, PartialEq, Eq)]
23#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
24pub enum CallFunctionResult {
25    Ok(SerializedValue),
26    Err(SerializedValue),
27    Aborted,
28    InvalidService,
29    InvalidFunction,
30    InvalidArgs,
31}
32
33impl CallFunctionResult {
34    pub fn ok_with_serialize_value<T: Serialize + ?Sized>(
35        value: &T,
36    ) -> Result<Self, SerializeError> {
37        SerializedValue::serialize(value).map(Self::Ok)
38    }
39
40    pub fn err_with_serialize_value<T: Serialize + ?Sized>(
41        value: &T,
42    ) -> Result<Self, SerializeError> {
43        SerializedValue::serialize(value).map(Self::Err)
44    }
45}
46
47#[derive(Debug, Clone, PartialEq, Eq)]
48#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
49pub struct CallFunctionReply {
50    pub serial: u32,
51    pub result: CallFunctionResult,
52}
53
54impl CallFunctionReply {
55    pub fn ok_with_serialize_value<T: Serialize + ?Sized>(
56        serial: u32,
57        value: &T,
58    ) -> Result<Self, SerializeError> {
59        let result = CallFunctionResult::ok_with_serialize_value(value)?;
60        Ok(Self { serial, result })
61    }
62
63    pub fn err_with_serialize_value<T: Serialize + ?Sized>(
64        serial: u32,
65        value: &T,
66    ) -> Result<Self, SerializeError> {
67        let result = CallFunctionResult::err_with_serialize_value(value)?;
68        Ok(Self { serial, result })
69    }
70}
71
72impl MessageOps for CallFunctionReply {
73    fn kind(&self) -> MessageKind {
74        MessageKind::CallFunctionReply
75    }
76
77    fn serialize_message(self) -> Result<BytesMut, MessageSerializeError> {
78        let serializer = match self.result {
79            CallFunctionResult::Ok(value) => {
80                let mut serializer =
81                    MessageSerializer::with_value(value, MessageKind::CallFunctionReply)?;
82                serializer.put_varint_u32_le(self.serial);
83                serializer.put_discriminant_u8(CallFunctionReplyKind::Ok);
84                serializer
85            }
86
87            CallFunctionResult::Err(value) => {
88                let mut serializer =
89                    MessageSerializer::with_value(value, MessageKind::CallFunctionReply)?;
90                serializer.put_varint_u32_le(self.serial);
91                serializer.put_discriminant_u8(CallFunctionReplyKind::Err);
92                serializer
93            }
94
95            CallFunctionResult::Aborted => {
96                let mut serializer =
97                    MessageSerializer::with_none_value(MessageKind::CallFunctionReply);
98                serializer.put_varint_u32_le(self.serial);
99                serializer.put_discriminant_u8(CallFunctionReplyKind::Aborted);
100                serializer
101            }
102
103            CallFunctionResult::InvalidService => {
104                let mut serializer =
105                    MessageSerializer::with_none_value(MessageKind::CallFunctionReply);
106                serializer.put_varint_u32_le(self.serial);
107                serializer.put_discriminant_u8(CallFunctionReplyKind::InvalidService);
108                serializer
109            }
110
111            CallFunctionResult::InvalidFunction => {
112                let mut serializer =
113                    MessageSerializer::with_none_value(MessageKind::CallFunctionReply);
114                serializer.put_varint_u32_le(self.serial);
115                serializer.put_discriminant_u8(CallFunctionReplyKind::InvalidFunction);
116                serializer
117            }
118
119            CallFunctionResult::InvalidArgs => {
120                let mut serializer =
121                    MessageSerializer::with_none_value(MessageKind::CallFunctionReply);
122                serializer.put_varint_u32_le(self.serial);
123                serializer.put_discriminant_u8(CallFunctionReplyKind::InvalidArgs);
124                serializer
125            }
126        };
127
128        serializer.finish()
129    }
130
131    fn deserialize_message(buf: BytesMut) -> Result<Self, MessageDeserializeError> {
132        let mut deserializer =
133            MessageWithValueDeserializer::new(buf, MessageKind::CallFunctionReply)?;
134
135        let serial = deserializer.try_get_varint_u32_le()?;
136
137        match deserializer.try_get_discriminant_u8()? {
138            CallFunctionReplyKind::Ok => {
139                let value = deserializer.finish()?;
140                Ok(Self {
141                    serial,
142                    result: CallFunctionResult::Ok(value),
143                })
144            }
145
146            CallFunctionReplyKind::Err => {
147                let value = deserializer.finish()?;
148                Ok(Self {
149                    serial,
150                    result: CallFunctionResult::Err(value),
151                })
152            }
153
154            CallFunctionReplyKind::Aborted => {
155                deserializer.finish_discard_value()?;
156                Ok(Self {
157                    serial,
158                    result: CallFunctionResult::Aborted,
159                })
160            }
161
162            CallFunctionReplyKind::InvalidService => {
163                deserializer.finish_discard_value()?;
164                Ok(Self {
165                    serial,
166                    result: CallFunctionResult::InvalidService,
167                })
168            }
169
170            CallFunctionReplyKind::InvalidFunction => {
171                deserializer.finish_discard_value()?;
172                Ok(Self {
173                    serial,
174                    result: CallFunctionResult::InvalidFunction,
175                })
176            }
177
178            CallFunctionReplyKind::InvalidArgs => {
179                deserializer.finish_discard_value()?;
180                Ok(Self {
181                    serial,
182                    result: CallFunctionResult::InvalidArgs,
183                })
184            }
185        }
186    }
187
188    fn value(&self) -> Option<&SerializedValueSlice> {
189        match self.result {
190            CallFunctionResult::Ok(ref value) | CallFunctionResult::Err(ref value) => Some(value),
191
192            CallFunctionResult::Aborted
193            | CallFunctionResult::InvalidService
194            | CallFunctionResult::InvalidFunction
195            | CallFunctionResult::InvalidArgs => None,
196        }
197    }
198}
199
200impl Sealed for CallFunctionReply {}
201
202impl From<CallFunctionReply> for Message {
203    fn from(msg: CallFunctionReply) -> Self {
204        Self::CallFunctionReply(msg)
205    }
206}
207
208#[cfg(test)]
209mod test {
210    use super::super::test::{
211        assert_deserialize_eq, assert_deserialize_eq_with_value, assert_serialize_eq,
212    };
213    use super::super::Message;
214    use super::{CallFunctionReply, CallFunctionResult};
215
216    #[test]
217    fn ok() {
218        let serialized = [13, 0, 0, 0, 12, 2, 0, 0, 0, 3, 4, 1, 0];
219        let value = 4u8;
220
221        let msg = CallFunctionReply::ok_with_serialize_value(1, &value).unwrap();
222        assert_serialize_eq(&msg, serialized);
223        assert_deserialize_eq_with_value(&msg, serialized, &value);
224
225        let msg = Message::CallFunctionReply(msg);
226        assert_serialize_eq(&msg, serialized);
227        assert_deserialize_eq_with_value(&msg, serialized, &value);
228    }
229
230    #[test]
231    fn err() {
232        let serialized = [13, 0, 0, 0, 12, 2, 0, 0, 0, 3, 4, 1, 1];
233        let value = 4u8;
234
235        let msg = CallFunctionReply::err_with_serialize_value(1, &value).unwrap();
236        assert_serialize_eq(&msg, serialized);
237        assert_deserialize_eq_with_value(&msg, serialized, &value);
238
239        let msg = Message::CallFunctionReply(msg);
240        assert_serialize_eq(&msg, serialized);
241        assert_deserialize_eq_with_value(&msg, serialized, &value);
242    }
243
244    #[test]
245    fn aborted() {
246        let serialized = [12, 0, 0, 0, 12, 1, 0, 0, 0, 0, 1, 2];
247
248        let msg = CallFunctionReply {
249            serial: 1,
250            result: CallFunctionResult::Aborted,
251        };
252        assert_serialize_eq(&msg, serialized);
253        assert_deserialize_eq(&msg, serialized);
254
255        let msg = Message::CallFunctionReply(msg);
256        assert_serialize_eq(&msg, serialized);
257        assert_deserialize_eq(&msg, serialized);
258    }
259
260    #[test]
261    fn invalid_service() {
262        let serialized = [12, 0, 0, 0, 12, 1, 0, 0, 0, 0, 1, 3];
263
264        let msg = CallFunctionReply {
265            serial: 1,
266            result: CallFunctionResult::InvalidService,
267        };
268        assert_serialize_eq(&msg, serialized);
269        assert_deserialize_eq(&msg, serialized);
270
271        let msg = Message::CallFunctionReply(msg);
272        assert_serialize_eq(&msg, serialized);
273        assert_deserialize_eq(&msg, serialized);
274    }
275
276    #[test]
277    fn invalid_function() {
278        let serialized = [12, 0, 0, 0, 12, 1, 0, 0, 0, 0, 1, 4];
279
280        let msg = CallFunctionReply {
281            serial: 1,
282            result: CallFunctionResult::InvalidFunction,
283        };
284        assert_serialize_eq(&msg, serialized);
285        assert_deserialize_eq(&msg, serialized);
286
287        let msg = Message::CallFunctionReply(msg);
288        assert_serialize_eq(&msg, serialized);
289        assert_deserialize_eq(&msg, serialized);
290    }
291
292    #[test]
293    fn invalid_args() {
294        let serialized = [12, 0, 0, 0, 12, 1, 0, 0, 0, 0, 1, 5];
295
296        let msg = CallFunctionReply {
297            serial: 1,
298            result: CallFunctionResult::InvalidArgs,
299        };
300        assert_serialize_eq(&msg, serialized);
301        assert_deserialize_eq(&msg, serialized);
302
303        let msg = Message::CallFunctionReply(msg);
304        assert_serialize_eq(&msg, serialized);
305        assert_deserialize_eq(&msg, serialized);
306    }
307}