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