aldrin_core/message/
call_function_reply.rs

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