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}