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}