aldrin_core/message/
create_service_reply.rs

1use super::message_ops::Sealed;
2use super::{Message, MessageKind, MessageOps};
3use crate::ids::ServiceCookie;
4use crate::message_deserializer::{MessageDeserializeError, MessageWithoutValueDeserializer};
5use crate::message_serializer::{MessageSerializeError, MessageSerializer};
6use crate::serialized_value::SerializedValueSlice;
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
93impl Sealed for CreateServiceReply {}
94
95impl From<CreateServiceReply> for Message {
96    fn from(msg: CreateServiceReply) -> Self {
97        Self::CreateServiceReply(msg)
98    }
99}
100
101#[cfg(test)]
102mod test {
103    use super::super::test::{assert_deserialize_eq, assert_serialize_eq};
104    use super::super::Message;
105    use super::{CreateServiceReply, CreateServiceResult};
106    use crate::ids::ServiceCookie;
107    use uuid::uuid;
108
109    #[test]
110    fn ok() {
111        let serialized = [
112            23, 0, 0, 0, 8, 1, 0, 0xb7, 0xc3, 0xbe, 0x13, 0x53, 0x77, 0x46, 0x6e, 0xb4, 0xbf, 0x37,
113            0x38, 0x76, 0x52, 0x3d, 0x1b,
114        ];
115
116        let msg = CreateServiceReply {
117            serial: 1,
118            result: CreateServiceResult::Ok(ServiceCookie(uuid!(
119                "b7c3be13-5377-466e-b4bf-373876523d1b"
120            ))),
121        };
122        assert_serialize_eq(&msg, serialized);
123        assert_deserialize_eq(&msg, serialized);
124
125        let msg = Message::CreateServiceReply(msg);
126        assert_serialize_eq(&msg, serialized);
127        assert_deserialize_eq(&msg, serialized);
128    }
129
130    #[test]
131    fn duplicate_service() {
132        let serialized = [7, 0, 0, 0, 8, 1, 1];
133
134        let msg = CreateServiceReply {
135            serial: 1,
136            result: CreateServiceResult::DuplicateService,
137        };
138        assert_serialize_eq(&msg, serialized);
139        assert_deserialize_eq(&msg, serialized);
140
141        let msg = Message::CreateServiceReply(msg);
142        assert_serialize_eq(&msg, serialized);
143        assert_deserialize_eq(&msg, serialized);
144    }
145
146    #[test]
147    fn invalid_object() {
148        let serialized = [7, 0, 0, 0, 8, 1, 2];
149
150        let msg = CreateServiceReply {
151            serial: 1,
152            result: CreateServiceResult::InvalidObject,
153        };
154        assert_serialize_eq(&msg, serialized);
155        assert_deserialize_eq(&msg, serialized);
156
157        let msg = Message::CreateServiceReply(msg);
158        assert_serialize_eq(&msg, serialized);
159        assert_deserialize_eq(&msg, serialized);
160    }
161
162    #[test]
163    fn foreign_object() {
164        let serialized = [7, 0, 0, 0, 8, 1, 3];
165
166        let msg = CreateServiceReply {
167            serial: 1,
168            result: CreateServiceResult::ForeignObject,
169        };
170        assert_serialize_eq(&msg, serialized);
171        assert_deserialize_eq(&msg, serialized);
172
173        let msg = Message::CreateServiceReply(msg);
174        assert_serialize_eq(&msg, serialized);
175        assert_deserialize_eq(&msg, serialized);
176    }
177}