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}