aldrin_core/message/
call_function2.rs

1use super::message_ops::Sealed;
2use super::{
3    Message, MessageDeserializeError, MessageKind, MessageOps, MessageSerializeError,
4    MessageSerializer, MessageWithValueDeserializer, OptionKind,
5};
6use crate::{SerializedValue, SerializedValueSlice, ServiceCookie};
7use bytes::BytesMut;
8
9#[derive(Debug, Clone, PartialEq, Eq)]
10#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
11pub struct CallFunction2 {
12    pub serial: u32,
13    pub service_cookie: ServiceCookie,
14    pub function: u32,
15    pub version: Option<u32>,
16    pub value: SerializedValue,
17}
18
19impl MessageOps for CallFunction2 {
20    fn kind(&self) -> MessageKind {
21        MessageKind::CallFunction2
22    }
23
24    fn serialize_message(self) -> Result<BytesMut, MessageSerializeError> {
25        let mut serializer = MessageSerializer::with_value(self.value, MessageKind::CallFunction2)?;
26
27        serializer.put_varint_u32_le(self.serial);
28        serializer.put_uuid(self.service_cookie.0);
29        serializer.put_varint_u32_le(self.function);
30
31        match self.version {
32            None => {
33                serializer.put_discriminant_u8(OptionKind::None);
34            }
35
36            Some(version) => {
37                serializer.put_discriminant_u8(OptionKind::Some);
38                serializer.put_varint_u32_le(version);
39            }
40        }
41
42        serializer.finish()
43    }
44
45    fn deserialize_message(buf: BytesMut) -> Result<Self, MessageDeserializeError> {
46        let mut deserializer = MessageWithValueDeserializer::new(buf, MessageKind::CallFunction2)?;
47
48        let serial = deserializer.try_get_varint_u32_le()?;
49        let service_cookie = deserializer.try_get_uuid().map(ServiceCookie)?;
50        let function = deserializer.try_get_varint_u32_le()?;
51
52        let version = match deserializer.try_get_discriminant_u8()? {
53            OptionKind::None => None,
54            OptionKind::Some => deserializer.try_get_varint_u32_le().map(Some)?,
55        };
56
57        let value = deserializer.finish()?;
58
59        Ok(Self {
60            serial,
61            service_cookie,
62            function,
63            version,
64            value,
65        })
66    }
67
68    fn value(&self) -> Option<&SerializedValueSlice> {
69        Some(&self.value)
70    }
71
72    fn value_mut(&mut self) -> Option<&mut SerializedValue> {
73        Some(&mut self.value)
74    }
75}
76
77impl Sealed for CallFunction2 {}
78
79impl From<CallFunction2> for Message {
80    fn from(msg: CallFunction2) -> Self {
81        Self::CallFunction2(msg)
82    }
83}
84
85#[cfg(test)]
86mod test {
87    use super::super::test::{assert_deserialize_eq_with_value, assert_serialize_eq};
88    use super::super::Message;
89    use super::CallFunction2;
90    use crate::{tags, SerializedValue, ServiceCookie};
91    use uuid::uuid;
92
93    #[test]
94    fn call_function2_without_version() {
95        let serialized = [
96            30, 0, 0, 0, 62, 2, 0, 0, 0, 3, 4, 1, 0x02, 0x6c, 0x31, 0x42, 0x53, 0x0b, 0x4d, 0x65,
97            0x85, 0x0d, 0xa2, 0x97, 0xdc, 0xc2, 0xfe, 0xcb, 2, 0,
98        ];
99        let value = 4u8;
100
101        let msg = CallFunction2 {
102            serial: 1,
103            service_cookie: ServiceCookie(uuid!("026c3142-530b-4d65-850d-a297dcc2fecb")),
104            function: 2,
105            version: None,
106            value: SerializedValue::serialize(value).unwrap(),
107        };
108
109        assert_serialize_eq(&msg, serialized);
110        assert_deserialize_eq_with_value::<_, _, tags::U8, _>(&msg, serialized, &value);
111
112        let msg = Message::CallFunction2(msg);
113        assert_serialize_eq(&msg, serialized);
114        assert_deserialize_eq_with_value::<_, _, tags::U8, _>(&msg, serialized, &value);
115    }
116
117    #[test]
118    fn call_function2_with_version() {
119        let serialized = [
120            31, 0, 0, 0, 62, 2, 0, 0, 0, 3, 4, 1, 0x02, 0x6c, 0x31, 0x42, 0x53, 0x0b, 0x4d, 0x65,
121            0x85, 0x0d, 0xa2, 0x97, 0xdc, 0xc2, 0xfe, 0xcb, 2, 1, 3,
122        ];
123        let value = 4u8;
124
125        let msg = CallFunction2 {
126            serial: 1,
127            service_cookie: ServiceCookie(uuid!("026c3142-530b-4d65-850d-a297dcc2fecb")),
128            function: 2,
129            version: Some(3),
130            value: SerializedValue::serialize(value).unwrap(),
131        };
132
133        assert_serialize_eq(&msg, serialized);
134        assert_deserialize_eq_with_value::<_, _, tags::U8, _>(&msg, serialized, &value);
135
136        let msg = Message::CallFunction2(msg);
137        assert_serialize_eq(&msg, serialized);
138        assert_deserialize_eq_with_value::<_, _, tags::U8, _>(&msg, serialized, &value);
139    }
140}