aldrin_core/message/
call_function.rs

1use 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}