aldrin_core/message/
call_function.rs1use super::message_ops::Sealed;
2use super::{Message, MessageKind, MessageOps};
3use crate::error::SerializeError;
4use crate::ids::ServiceCookie;
5use crate::message_deserializer::{MessageDeserializeError, MessageWithValueDeserializer};
6use crate::message_serializer::{MessageSerializeError, MessageSerializer};
7use crate::serialized_value::{SerializedValue, SerializedValueSlice};
8use crate::value_serializer::Serialize;
9use bytes::BytesMut;
10
11#[derive(Debug, Clone, PartialEq, Eq)]
12#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
13pub struct CallFunction {
14 pub serial: u32,
15 pub service_cookie: ServiceCookie,
16 pub function: u32,
17 pub value: SerializedValue,
18}
19
20impl CallFunction {
21 pub fn with_serialize_value<T: Serialize + ?Sized>(
22 serial: u32,
23 service_cookie: ServiceCookie,
24 function: u32,
25 value: &T,
26 ) -> Result<Self, SerializeError> {
27 let value = SerializedValue::serialize(value)?;
28 Ok(Self {
29 serial,
30 service_cookie,
31 function,
32 value,
33 })
34 }
35}
36
37impl MessageOps for CallFunction {
38 fn kind(&self) -> MessageKind {
39 MessageKind::CallFunction
40 }
41
42 fn serialize_message(self) -> Result<BytesMut, MessageSerializeError> {
43 let mut serializer = MessageSerializer::with_value(self.value, MessageKind::CallFunction)?;
44
45 serializer.put_varint_u32_le(self.serial);
46 serializer.put_uuid(self.service_cookie.0);
47 serializer.put_varint_u32_le(self.function);
48
49 serializer.finish()
50 }
51
52 fn deserialize_message(buf: BytesMut) -> Result<Self, MessageDeserializeError> {
53 let mut deserializer = MessageWithValueDeserializer::new(buf, MessageKind::CallFunction)?;
54
55 let serial = deserializer.try_get_varint_u32_le()?;
56 let service_cookie = deserializer.try_get_uuid().map(ServiceCookie)?;
57 let function = deserializer.try_get_varint_u32_le()?;
58 let value = deserializer.finish()?;
59
60 Ok(Self {
61 serial,
62 service_cookie,
63 function,
64 value,
65 })
66 }
67
68 fn value(&self) -> Option<&SerializedValueSlice> {
69 Some(&self.value)
70 }
71}
72
73impl Sealed for CallFunction {}
74
75impl From<CallFunction> for Message {
76 fn from(msg: CallFunction) -> Self {
77 Self::CallFunction(msg)
78 }
79}
80
81#[cfg(test)]
82mod test {
83 use super::super::test::{assert_deserialize_eq_with_value, assert_serialize_eq};
84 use super::super::Message;
85 use super::CallFunction;
86 use crate::ids::ServiceCookie;
87 use uuid::uuid;
88
89 #[test]
90 fn call_function() {
91 let serialized = [
92 29, 0, 0, 0, 11, 2, 0, 0, 0, 3, 4, 1, 0x02, 0x6c, 0x31, 0x42, 0x53, 0x0b, 0x4d, 0x65,
93 0x85, 0x0d, 0xa2, 0x97, 0xdc, 0xc2, 0xfe, 0xcb, 2,
94 ];
95 let value = 4u8;
96
97 let msg = CallFunction::with_serialize_value(
98 1,
99 ServiceCookie(uuid!("026c3142-530b-4d65-850d-a297dcc2fecb")),
100 2,
101 &value,
102 )
103 .unwrap();
104 assert_serialize_eq(&msg, serialized);
105 assert_deserialize_eq_with_value(&msg, serialized, &value);
106
107 let msg = Message::CallFunction(msg);
108 assert_serialize_eq(&msg, serialized);
109 assert_deserialize_eq_with_value(&msg, serialized, &value);
110 }
111}