aldrin_core/message/
connect2.rs

1use super::message_ops::Sealed;
2use super::{
3    Message, MessageDeserializeError, MessageKind, MessageOps, MessageSerializeError,
4    MessageSerializer, MessageWithValueDeserializer,
5};
6use crate::tags::{self, PrimaryTag, Tag};
7use crate::{
8    Deserialize, DeserializeError, DeserializePrimary, Deserializer, Serialize, SerializeError,
9    SerializePrimary, SerializedValue, SerializedValueSlice, Serializer,
10};
11use bytes::BytesMut;
12use num_enum::{IntoPrimitive, TryFromPrimitive};
13
14#[derive(Debug, Clone, PartialEq, Eq, Default)]
15#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
16pub struct ConnectData {
17    pub user: Option<SerializedValue>,
18}
19
20impl ConnectData {
21    pub fn new() -> Self {
22        Self::default()
23    }
24
25    pub fn serialize_user_as<T: Tag>(
26        &mut self,
27        user: impl Serialize<T>,
28    ) -> Result<&mut Self, SerializeError> {
29        self.user = SerializedValue::serialize_as(user).map(Some)?;
30        Ok(self)
31    }
32
33    pub fn serialize_user(
34        &mut self,
35        user: impl SerializePrimary,
36    ) -> Result<&mut Self, SerializeError> {
37        self.serialize_user_as(user)
38    }
39
40    pub fn deserialize_user_as<T: Tag, U: Deserialize<T>>(
41        &self,
42    ) -> Option<Result<U, DeserializeError>> {
43        self.user
44            .as_deref()
45            .map(SerializedValueSlice::deserialize_as)
46    }
47
48    pub fn deserialize_user<T: DeserializePrimary>(&self) -> Option<Result<T, DeserializeError>> {
49        self.deserialize_user_as()
50    }
51}
52
53impl Tag for ConnectData {}
54
55impl PrimaryTag for ConnectData {
56    type Tag = Self;
57}
58
59#[derive(IntoPrimitive, TryFromPrimitive)]
60#[repr(u32)]
61enum ConnectDataField {
62    User = 0,
63}
64
65impl Serialize<Self> for ConnectData {
66    fn serialize(self, serializer: Serializer) -> Result<(), SerializeError> {
67        serializer.serialize(&self)
68    }
69}
70
71impl Serialize<ConnectData> for &ConnectData {
72    fn serialize(self, serializer: Serializer) -> Result<(), SerializeError> {
73        let mut serializer = serializer.serialize_struct2()?;
74
75        serializer
76            .serialize_if_some::<tags::Option<tags::Value>>(ConnectDataField::User, &self.user)?;
77
78        serializer.finish()
79    }
80}
81
82impl Deserialize<Self> for ConnectData {
83    fn deserialize(deserializer: Deserializer) -> Result<Self, DeserializeError> {
84        let mut deserializer = deserializer.deserialize_struct()?;
85
86        let mut user = None;
87
88        while let Some(deserializer) = deserializer.deserialize()? {
89            match deserializer.try_id() {
90                Ok(ConnectDataField::User) => user = deserializer.deserialize()?,
91                Err(_) => deserializer.skip()?,
92            }
93        }
94
95        deserializer.finish(Self { user })
96    }
97}
98
99#[derive(Debug, Clone, PartialEq, Eq)]
100#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
101pub struct Connect2 {
102    pub major_version: u32,
103    pub minor_version: u32,
104    pub value: SerializedValue,
105}
106
107impl MessageOps for Connect2 {
108    fn kind(&self) -> MessageKind {
109        MessageKind::Connect2
110    }
111
112    fn serialize_message(self) -> Result<BytesMut, MessageSerializeError> {
113        let mut serializer = MessageSerializer::with_value(self.value, MessageKind::Connect2)?;
114
115        serializer.put_varint_u32_le(self.major_version);
116        serializer.put_varint_u32_le(self.minor_version);
117
118        serializer.finish()
119    }
120
121    fn deserialize_message(buf: BytesMut) -> Result<Self, MessageDeserializeError> {
122        let mut deserializer = MessageWithValueDeserializer::new(buf, MessageKind::Connect2)?;
123
124        let major_version = deserializer.try_get_varint_u32_le()?;
125        let minor_version = deserializer.try_get_varint_u32_le()?;
126        let value = deserializer.finish()?;
127
128        Ok(Self {
129            major_version,
130            minor_version,
131            value,
132        })
133    }
134
135    fn value(&self) -> Option<&SerializedValueSlice> {
136        Some(&self.value)
137    }
138
139    fn value_mut(&mut self) -> Option<&mut SerializedValue> {
140        Some(&mut self.value)
141    }
142}
143
144impl Sealed for Connect2 {}
145
146impl From<Connect2> for Message {
147    fn from(msg: Connect2) -> Self {
148        Self::Connect2(msg)
149    }
150}
151
152#[cfg(test)]
153mod test {
154    use super::super::test::{assert_deserialize_eq_with_value, assert_serialize_eq};
155    use super::super::Message;
156    use super::{Connect2, ConnectData};
157    use crate::SerializedValue;
158
159    #[test]
160    fn connect2() {
161        let serialized = [13, 0, 0, 0, 46, 2, 0, 0, 0, 65, 0, 1, 2];
162        let value = ConnectData::new();
163
164        let msg = Connect2 {
165            major_version: 1,
166            minor_version: 2,
167            value: SerializedValue::serialize(&value).unwrap(),
168        };
169        assert_serialize_eq(&msg, serialized);
170        assert_deserialize_eq_with_value(&msg, serialized, &value);
171
172        let msg = Message::Connect2(msg);
173        assert_serialize_eq(&msg, serialized);
174        assert_deserialize_eq_with_value(&msg, serialized, &value);
175    }
176}