aldrin_core/message/
connect_reply2.rs

1use super::message_ops::Sealed;
2use super::{Message, MessageKind, MessageOps};
3use crate::error::{DeserializeError, SerializeError};
4use crate::message_deserializer::{MessageDeserializeError, MessageWithValueDeserializer};
5use crate::message_serializer::{MessageSerializeError, MessageSerializer};
6use crate::serialized_value::{SerializedValue, SerializedValueSlice};
7use crate::value_deserializer::{Deserialize, Deserializer};
8use crate::value_serializer::{Serialize, Serializer};
9use bytes::BytesMut;
10use num_enum::{IntoPrimitive, TryFromPrimitive};
11
12#[derive(Debug, Clone, PartialEq, Eq, Default)]
13#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
14pub struct ConnectReplyData {
15    pub user: Option<SerializedValue>,
16}
17
18impl ConnectReplyData {
19    pub fn new() -> Self {
20        Self::default()
21    }
22
23    pub fn serialize_user<T: Serialize + ?Sized>(
24        &mut self,
25        user: &T,
26    ) -> Result<&mut Self, SerializeError> {
27        self.user = SerializedValue::serialize(user).map(Some)?;
28        Ok(self)
29    }
30
31    pub fn deserialize_user<T: Deserialize>(&self) -> Option<Result<T, DeserializeError>> {
32        self.user.as_deref().map(SerializedValueSlice::deserialize)
33    }
34}
35
36impl Serialize for ConnectReplyData {
37    fn serialize(&self, serializer: Serializer) -> Result<(), SerializeError> {
38        let mut serializer = serializer.serialize_struct(1)?;
39        serializer.serialize_field(0, &self.user)?;
40        serializer.finish()
41    }
42}
43
44impl Deserialize for ConnectReplyData {
45    fn deserialize(deserializer: Deserializer) -> Result<Self, DeserializeError> {
46        let mut deserializer = deserializer.deserialize_struct()?;
47
48        let mut user = None;
49
50        while deserializer.has_more_fields() {
51            let deserializer = deserializer.deserialize_field()?;
52
53            match deserializer.id() {
54                0 => user = deserializer.deserialize()?,
55                _ => deserializer.skip()?,
56            }
57        }
58
59        Ok(Self { user })
60    }
61}
62
63#[derive(Debug, Copy, Clone, PartialEq, Eq, IntoPrimitive, TryFromPrimitive)]
64#[repr(u8)]
65enum ConnectReplyKind {
66    Ok = 0,
67    Rejected = 1,
68    IncompatibleVersion = 2,
69}
70
71#[derive(Debug, Copy, Clone, PartialEq, Eq)]
72#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
73pub enum ConnectResult {
74    Ok(u32),
75    Rejected,
76    IncompatibleVersion,
77}
78
79#[derive(Debug, Clone, PartialEq, Eq)]
80#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
81pub struct ConnectReply2 {
82    pub result: ConnectResult,
83    pub value: SerializedValue,
84}
85
86impl ConnectReply2 {
87    pub fn ok_with_serialize_data(
88        version: u32,
89        data: &ConnectReplyData,
90    ) -> Result<Self, SerializeError> {
91        let value = SerializedValue::serialize(data)?;
92
93        Ok(Self {
94            result: ConnectResult::Ok(version),
95            value,
96        })
97    }
98
99    pub fn rejected_with_serialize_data(data: &ConnectReplyData) -> Result<Self, SerializeError> {
100        let value = SerializedValue::serialize(data)?;
101
102        Ok(Self {
103            result: ConnectResult::Rejected,
104            value,
105        })
106    }
107
108    pub fn incompatible_version_with_serialize_data(
109        data: &ConnectReplyData,
110    ) -> Result<Self, SerializeError> {
111        let value = SerializedValue::serialize(data)?;
112
113        Ok(Self {
114            result: ConnectResult::IncompatibleVersion,
115            value,
116        })
117    }
118
119    pub fn deserialize_connect_data(&self) -> Result<ConnectReplyData, DeserializeError> {
120        self.value.deserialize()
121    }
122}
123
124impl MessageOps for ConnectReply2 {
125    fn kind(&self) -> MessageKind {
126        MessageKind::ConnectReply2
127    }
128
129    fn serialize_message(self) -> Result<BytesMut, MessageSerializeError> {
130        let mut serializer = MessageSerializer::with_value(self.value, MessageKind::ConnectReply2)?;
131
132        match self.result {
133            ConnectResult::Ok(version) => {
134                serializer.put_discriminant_u8(ConnectReplyKind::Ok);
135                serializer.put_varint_u32_le(version);
136                serializer.finish()
137            }
138
139            ConnectResult::Rejected => {
140                serializer.put_discriminant_u8(ConnectReplyKind::Rejected);
141                serializer.finish()
142            }
143
144            ConnectResult::IncompatibleVersion => {
145                serializer.put_discriminant_u8(ConnectReplyKind::IncompatibleVersion);
146                serializer.finish()
147            }
148        }
149    }
150
151    fn deserialize_message(buf: BytesMut) -> Result<Self, MessageDeserializeError> {
152        let mut deserializer = MessageWithValueDeserializer::new(buf, MessageKind::ConnectReply2)?;
153
154        match deserializer.try_get_discriminant_u8()? {
155            ConnectReplyKind::Ok => {
156                let version = deserializer.try_get_varint_u32_le()?;
157                let value = deserializer.finish()?;
158
159                Ok(Self {
160                    result: ConnectResult::Ok(version),
161                    value,
162                })
163            }
164
165            ConnectReplyKind::Rejected => {
166                let value = deserializer.finish()?;
167
168                Ok(Self {
169                    result: ConnectResult::Rejected,
170                    value,
171                })
172            }
173
174            ConnectReplyKind::IncompatibleVersion => {
175                let value = deserializer.finish()?;
176
177                Ok(Self {
178                    result: ConnectResult::IncompatibleVersion,
179                    value,
180                })
181            }
182        }
183    }
184
185    fn value(&self) -> Option<&SerializedValueSlice> {
186        Some(&self.value)
187    }
188}
189
190impl Sealed for ConnectReply2 {}
191
192impl From<ConnectReply2> for Message {
193    fn from(msg: ConnectReply2) -> Self {
194        Self::ConnectReply2(msg)
195    }
196}
197
198#[cfg(test)]
199mod test {
200    use super::super::test::{assert_deserialize_eq_with_value, assert_serialize_eq};
201    use super::super::Message;
202    use super::{ConnectReply2, ConnectReplyData};
203
204    #[test]
205    fn ok() {
206        let serialized = [15, 0, 0, 0, 47, 4, 0, 0, 0, 39, 1, 0, 0, 0, 1];
207        let value = ConnectReplyData::new();
208
209        let msg = ConnectReply2::ok_with_serialize_data(1, &value).unwrap();
210        assert_serialize_eq(&msg, serialized);
211        assert_deserialize_eq_with_value(&msg, serialized, &value);
212
213        let msg = Message::ConnectReply2(msg);
214        assert_serialize_eq(&msg, serialized);
215        assert_deserialize_eq_with_value(&msg, serialized, &value);
216    }
217
218    #[test]
219    fn rejected() {
220        let serialized = [14, 0, 0, 0, 47, 4, 0, 0, 0, 39, 1, 0, 0, 1];
221        let value = ConnectReplyData::new();
222
223        let msg = ConnectReply2::rejected_with_serialize_data(&value).unwrap();
224        assert_serialize_eq(&msg, serialized);
225        assert_deserialize_eq_with_value(&msg, serialized, &value);
226
227        let msg = Message::ConnectReply2(msg);
228        assert_serialize_eq(&msg, serialized);
229        assert_deserialize_eq_with_value(&msg, serialized, &value);
230    }
231
232    #[test]
233    fn incompatible_version() {
234        let serialized = [14, 0, 0, 0, 47, 4, 0, 0, 0, 39, 1, 0, 0, 2];
235        let value = ConnectReplyData::new();
236
237        let msg = ConnectReply2::incompatible_version_with_serialize_data(&value).unwrap();
238        assert_serialize_eq(&msg, serialized);
239        assert_deserialize_eq_with_value(&msg, serialized, &value);
240
241        let msg = Message::ConnectReply2(msg);
242        assert_serialize_eq(&msg, serialized);
243        assert_deserialize_eq_with_value(&msg, serialized, &value);
244    }
245}