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}