aldrin_core/message/
query_service_info_reply.rs

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}