1use super::message_ops::Sealed;
2use super::{
3 Message, MessageDeserializeError, MessageKind, MessageOps, MessageSerializeError,
4 MessageSerializer, MessageWithValueDeserializer,
5};
6use crate::{SerializedValue, SerializedValueSlice};
7use bytes::BytesMut;
8use num_enum::{IntoPrimitive, TryFromPrimitive};
9
10#[derive(Debug, Copy, Clone, PartialEq, Eq, IntoPrimitive, TryFromPrimitive)]
11#[repr(u8)]
12enum QueryServiceInfoReplyKind {
13 Ok = 0,
14 InvalidService = 1,
15}
16
17#[derive(Debug, Clone, PartialEq, Eq)]
18#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
19pub enum QueryServiceInfoResult {
20 Ok(SerializedValue),
21 InvalidService,
22}
23
24#[derive(Debug, Clone, PartialEq, Eq)]
25#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
26pub struct QueryServiceInfoReply {
27 pub serial: u32,
28 pub result: QueryServiceInfoResult,
29}
30
31impl MessageOps for QueryServiceInfoReply {
32 fn kind(&self) -> MessageKind {
33 MessageKind::QueryServiceInfoReply
34 }
35
36 fn serialize_message(self) -> Result<BytesMut, MessageSerializeError> {
37 let serializer = match self.result {
38 QueryServiceInfoResult::Ok(value) => {
39 let mut serializer =
40 MessageSerializer::with_value(value, MessageKind::QueryServiceInfoReply)?;
41
42 serializer.put_varint_u32_le(self.serial);
43 serializer.put_discriminant_u8(QueryServiceInfoReplyKind::Ok);
44
45 serializer
46 }
47
48 QueryServiceInfoResult::InvalidService => {
49 let mut serializer =
50 MessageSerializer::with_none_value(MessageKind::QueryServiceInfoReply);
51
52 serializer.put_varint_u32_le(self.serial);
53 serializer.put_discriminant_u8(QueryServiceInfoReplyKind::InvalidService);
54
55 serializer
56 }
57 };
58
59 serializer.finish()
60 }
61
62 fn deserialize_message(buf: BytesMut) -> Result<Self, MessageDeserializeError> {
63 let mut deserializer =
64 MessageWithValueDeserializer::new(buf, MessageKind::QueryServiceInfoReply)?;
65
66 let serial = deserializer.try_get_varint_u32_le()?;
67
68 match deserializer.try_get_discriminant_u8()? {
69 QueryServiceInfoReplyKind::Ok => {
70 let value = deserializer.finish()?;
71
72 Ok(Self {
73 serial,
74 result: QueryServiceInfoResult::Ok(value),
75 })
76 }
77
78 QueryServiceInfoReplyKind::InvalidService => {
79 deserializer.finish_discard_value()?;
80
81 Ok(Self {
82 serial,
83 result: QueryServiceInfoResult::InvalidService,
84 })
85 }
86 }
87 }
88
89 fn value(&self) -> Option<&SerializedValueSlice> {
90 match self.result {
91 QueryServiceInfoResult::Ok(ref value) => Some(value),
92 QueryServiceInfoResult::InvalidService => None,
93 }
94 }
95
96 fn value_mut(&mut self) -> Option<&mut SerializedValue> {
97 match self.result {
98 QueryServiceInfoResult::Ok(ref mut value) => Some(value),
99 QueryServiceInfoResult::InvalidService => None,
100 }
101 }
102}
103
104impl Sealed for QueryServiceInfoReply {}
105
106impl From<QueryServiceInfoReply> for Message {
107 fn from(msg: QueryServiceInfoReply) -> Self {
108 Self::QueryServiceInfoReply(msg)
109 }
110}
111
112#[cfg(test)]
113mod test {
114 use super::super::test::{
115 assert_deserialize_eq, assert_deserialize_eq_with_value, assert_serialize_eq,
116 };
117 use super::super::Message;
118 use super::{QueryServiceInfoReply, QueryServiceInfoResult};
119 use crate::{SerializedValue, ServiceInfo, TypeId};
120 use uuid::uuid;
121
122 #[test]
123 fn ok() {
124 let serialized = [
125 42, 0, 0, 0, 54, 31, 0, 0, 0, 65, 1, 0, 7, 2, 1, 1, 1, 14, 0xcf, 0x41, 0xc6, 0x88,
126 0x49, 0x76, 0x46, 0xa5, 0x8e, 0x2d, 0x48, 0x71, 0x02, 0x58, 0xbc, 0x2c, 1, 2, 1, 2, 1,
127 0, 1, 0,
128 ];
129 let value = ServiceInfo::new(2)
130 .set_type_id(TypeId(uuid!("cf41c688-4976-46a5-8e2d-48710258bc2c")))
131 .set_subscribe_all(true);
132
133 let msg = QueryServiceInfoReply {
134 serial: 1,
135 result: QueryServiceInfoResult::Ok(SerializedValue::serialize(value).unwrap()),
136 };
137
138 assert_serialize_eq(&msg, serialized);
139 assert_deserialize_eq_with_value(&msg, serialized, &value);
140
141 let msg = Message::QueryServiceInfoReply(msg);
142 assert_serialize_eq(&msg, serialized);
143 assert_deserialize_eq_with_value(&msg, serialized, &value);
144 }
145
146 #[test]
147 fn invalid_service() {
148 let serialized = [12, 0, 0, 0, 54, 1, 0, 0, 0, 0, 1, 1];
149
150 let msg = QueryServiceInfoReply {
151 serial: 1,
152 result: QueryServiceInfoResult::InvalidService,
153 };
154 assert_serialize_eq(&msg, serialized);
155 assert_deserialize_eq(&msg, serialized);
156
157 let msg = Message::QueryServiceInfoReply(msg);
158 assert_serialize_eq(&msg, serialized);
159 assert_deserialize_eq(&msg, serialized);
160 }
161}