aldrin_core/message/
create_service_reply.rs

1use super::message_ops::Sealed;
2use super::{
3    Message, MessageDeserializeError, MessageKind, MessageOps, MessageSerializeError,
4    MessageSerializer, MessageWithoutValueDeserializer,
5};
6use crate::{SerializedValue, SerializedValueSlice, ServiceCookie};
7use bytes::BytesMut;
8use num_enum::{IntoPrimitive, TryFromPrimitive};
9
10#[derive(Debug, Copy, Clone, PartialEq, Eq, IntoPrimitive, TryFromPrimitive)]
11#[repr(u8)]
12enum CreateServiceReplyKind {
13    Ok = 0,
14    DuplicateService = 1,
15    InvalidObject = 2,
16    ForeignObject = 3,
17}
18
19#[derive(Debug, Copy, Clone, PartialEq, Eq)]
20#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
21pub enum CreateServiceResult {
22    Ok(ServiceCookie),
23    DuplicateService,
24    InvalidObject,
25    ForeignObject,
26}
27
28#[derive(Debug, Copy, Clone, PartialEq, Eq)]
29#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
30pub struct CreateServiceReply {
31    pub serial: u32,
32    pub result: CreateServiceResult,
33}
34
35impl MessageOps for CreateServiceReply {
36    fn kind(&self) -> MessageKind {
37        MessageKind::CreateServiceReply
38    }
39
40    fn serialize_message(self) -> Result<BytesMut, MessageSerializeError> {
41        let mut serializer = MessageSerializer::without_value(MessageKind::CreateServiceReply);
42
43        serializer.put_varint_u32_le(self.serial);
44
45        match self.result {
46            CreateServiceResult::Ok(cookie) => {
47                serializer.put_discriminant_u8(CreateServiceReplyKind::Ok);
48                serializer.put_uuid(cookie.0);
49            }
50
51            CreateServiceResult::DuplicateService => {
52                serializer.put_discriminant_u8(CreateServiceReplyKind::DuplicateService);
53            }
54
55            CreateServiceResult::InvalidObject => {
56                serializer.put_discriminant_u8(CreateServiceReplyKind::InvalidObject);
57            }
58
59            CreateServiceResult::ForeignObject => {
60                serializer.put_discriminant_u8(CreateServiceReplyKind::ForeignObject);
61            }
62        }
63
64        serializer.finish()
65    }
66
67    fn deserialize_message(buf: BytesMut) -> Result<Self, MessageDeserializeError> {
68        let mut deserializer =
69            MessageWithoutValueDeserializer::new(buf, MessageKind::CreateServiceReply)?;
70
71        let serial = deserializer.try_get_varint_u32_le()?;
72
73        let result = match deserializer.try_get_discriminant_u8()? {
74            CreateServiceReplyKind::Ok => {
75                let cookie = deserializer.try_get_uuid().map(ServiceCookie)?;
76                CreateServiceResult::Ok(cookie)
77            }
78
79            CreateServiceReplyKind::DuplicateService => CreateServiceResult::DuplicateService,
80            CreateServiceReplyKind::InvalidObject => CreateServiceResult::InvalidObject,
81            CreateServiceReplyKind::ForeignObject => CreateServiceResult::ForeignObject,
82        };
83
84        deserializer.finish()?;
85        Ok(Self { serial, result })
86    }
87
88    fn value(&self) -> Option<&SerializedValueSlice> {
89        None
90    }
91
92    fn value_mut(&mut self) -> Option<&mut SerializedValue> {
93        None
94    }
95}
96
97impl Sealed for CreateServiceReply {}
98
99impl From<CreateServiceReply> for Message {
100    fn from(msg: CreateServiceReply) -> Self {
101        Self::CreateServiceReply(msg)
102    }
103}
104
105#[cfg(test)]
106mod test {
107    use super::super::test::{assert_deserialize_eq, assert_serialize_eq};
108    use super::super::Message;
109    use super::{CreateServiceReply, CreateServiceResult};
110    use crate::ServiceCookie;
111    use uuid::uuid;
112
113    #[test]
114    fn ok() {
115        let serialized = [
116            23, 0, 0, 0, 8, 1, 0, 0xb7, 0xc3, 0xbe, 0x13, 0x53, 0x77, 0x46, 0x6e, 0xb4, 0xbf, 0x37,
117            0x38, 0x76, 0x52, 0x3d, 0x1b,
118        ];
119
120        let msg = CreateServiceReply {
121            serial: 1,
122            result: CreateServiceResult::Ok(ServiceCookie(uuid!(
123                "b7c3be13-5377-466e-b4bf-373876523d1b"
124            ))),
125        };
126        assert_serialize_eq(&msg, serialized);
127        assert_deserialize_eq(&msg, serialized);
128
129        let msg = Message::CreateServiceReply(msg);
130        assert_serialize_eq(&msg, serialized);
131        assert_deserialize_eq(&msg, serialized);
132    }
133
134    #[test]
135    fn duplicate_service() {
136        let serialized = [7, 0, 0, 0, 8, 1, 1];
137
138        let msg = CreateServiceReply {
139            serial: 1,
140            result: CreateServiceResult::DuplicateService,
141        };
142        assert_serialize_eq(&msg, serialized);
143        assert_deserialize_eq(&msg, serialized);
144
145        let msg = Message::CreateServiceReply(msg);
146        assert_serialize_eq(&msg, serialized);
147        assert_deserialize_eq(&msg, serialized);
148    }
149
150    #[test]
151    fn invalid_object() {
152        let serialized = [7, 0, 0, 0, 8, 1, 2];
153
154        let msg = CreateServiceReply {
155            serial: 1,
156            result: CreateServiceResult::InvalidObject,
157        };
158        assert_serialize_eq(&msg, serialized);
159        assert_deserialize_eq(&msg, serialized);
160
161        let msg = Message::CreateServiceReply(msg);
162        assert_serialize_eq(&msg, serialized);
163        assert_deserialize_eq(&msg, serialized);
164    }
165
166    #[test]
167    fn foreign_object() {
168        let serialized = [7, 0, 0, 0, 8, 1, 3];
169
170        let msg = CreateServiceReply {
171            serial: 1,
172            result: CreateServiceResult::ForeignObject,
173        };
174        assert_serialize_eq(&msg, serialized);
175        assert_deserialize_eq(&msg, serialized);
176
177        let msg = Message::CreateServiceReply(msg);
178        assert_serialize_eq(&msg, serialized);
179        assert_deserialize_eq(&msg, serialized);
180    }
181}