aldrin_core/message/
connect2.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::{AsSerializeArg, 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 ConnectData {
15    pub user: Option<SerializedValue>,
16}
17
18impl ConnectData {
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
36#[derive(IntoPrimitive, TryFromPrimitive)]
37#[repr(u32)]
38enum ConnectDataField {
39    User = 0,
40}
41
42impl Serialize for ConnectData {
43    fn serialize(&self, serializer: Serializer) -> Result<(), SerializeError> {
44        let mut serializer = serializer.serialize_struct(1)?;
45        serializer.serialize_field(ConnectDataField::User, &self.user)?;
46        serializer.finish()
47    }
48}
49
50impl Deserialize for ConnectData {
51    fn deserialize(deserializer: Deserializer) -> Result<Self, DeserializeError> {
52        let mut deserializer = deserializer.deserialize_struct()?;
53
54        let mut user = None;
55
56        while deserializer.has_more_fields() {
57            let deserializer = deserializer.deserialize_field()?;
58
59            let Ok(field) = deserializer.try_id() else {
60                deserializer.skip()?;
61                continue;
62            };
63
64            match field {
65                ConnectDataField::User => user = deserializer.deserialize()?,
66            }
67        }
68
69        deserializer.finish(Self { user })
70    }
71}
72
73impl AsSerializeArg for ConnectData {
74    type SerializeArg<'a> = &'a Self;
75
76    fn as_serialize_arg<'a>(&'a self) -> Self::SerializeArg<'a>
77    where
78        Self: 'a,
79    {
80        self
81    }
82}
83
84#[derive(Debug, Clone, PartialEq, Eq)]
85#[cfg_attr(feature = "fuzzing", derive(arbitrary::Arbitrary))]
86pub struct Connect2 {
87    pub major_version: u32,
88    pub minor_version: u32,
89    pub value: SerializedValue,
90}
91
92impl Connect2 {
93    pub fn with_serialize_data(
94        major_version: u32,
95        minor_version: u32,
96        data: &ConnectData,
97    ) -> Result<Self, SerializeError> {
98        let value = SerializedValue::serialize(data)?;
99
100        Ok(Self {
101            major_version,
102            minor_version,
103            value,
104        })
105    }
106
107    pub fn deserialize_connect_data(&self) -> Result<ConnectData, DeserializeError> {
108        self.value.deserialize()
109    }
110}
111
112impl MessageOps for Connect2 {
113    fn kind(&self) -> MessageKind {
114        MessageKind::Connect2
115    }
116
117    fn serialize_message(self) -> Result<BytesMut, MessageSerializeError> {
118        let mut serializer = MessageSerializer::with_value(self.value, MessageKind::Connect2)?;
119
120        serializer.put_varint_u32_le(self.major_version);
121        serializer.put_varint_u32_le(self.minor_version);
122
123        serializer.finish()
124    }
125
126    fn deserialize_message(buf: BytesMut) -> Result<Self, MessageDeserializeError> {
127        let mut deserializer = MessageWithValueDeserializer::new(buf, MessageKind::Connect2)?;
128
129        let major_version = deserializer.try_get_varint_u32_le()?;
130        let minor_version = deserializer.try_get_varint_u32_le()?;
131        let value = deserializer.finish()?;
132
133        Ok(Self {
134            major_version,
135            minor_version,
136            value,
137        })
138    }
139
140    fn value(&self) -> Option<&SerializedValueSlice> {
141        Some(&self.value)
142    }
143}
144
145impl Sealed for Connect2 {}
146
147impl From<Connect2> for Message {
148    fn from(msg: Connect2) -> Self {
149        Self::Connect2(msg)
150    }
151}
152
153#[cfg(test)]
154mod test {
155    use super::super::test::{assert_deserialize_eq_with_value, assert_serialize_eq};
156    use super::super::Message;
157    use super::{Connect2, ConnectData};
158
159    #[test]
160    fn connect() {
161        let serialized = [15, 0, 0, 0, 46, 4, 0, 0, 0, 39, 1, 0, 0, 1, 2];
162        let value = ConnectData::new();
163
164        let msg = Connect2::with_serialize_data(1, 2, &value).unwrap();
165        assert_serialize_eq(&msg, serialized);
166        assert_deserialize_eq_with_value(&msg, serialized, &value);
167
168        let msg = Message::Connect2(msg);
169        assert_serialize_eq(&msg, serialized);
170        assert_deserialize_eq_with_value(&msg, serialized, &value);
171    }
172}