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