grammers_tl_types/serialize.rs
1// Copyright 2020 - developers of the `grammers` project.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! Traits involving the serialization of the generated objects.
10
11/// This trait allows for concrete instances to be serialized into
12/// binary data as specified by the [Binary Data Serialization].
13///
14/// [Binary Data Serialization]: https://core.telegram.org/mtproto/serialize
15pub trait Serializable {
16 /// Serializes the instance into the given buffer.
17 fn serialize(&self, buf: &mut impl Extend<u8>);
18
19 /// Convenience function to serialize the object into a new buffer
20 /// and return its bytes. It is more efficient to reuse a existing
21 /// buffer with [`Serializable::serialize`].
22 fn to_bytes(&self) -> Vec<u8> {
23 let mut buffer = Vec::new();
24 self.serialize(&mut buffer);
25 buffer
26 }
27}
28
29impl Serializable for bool {
30 /// Serializes the boolean according to the following definitions:
31 ///
32 /// * `false` is serialized as `boolFalse#bc799737 = Bool;`.
33 /// * `true` is serialized as `boolTrue#997275b5 = Bool;`.
34 ///
35 /// # Examples
36 ///
37 /// ```
38 /// use grammers_tl_types::Serializable;
39 ///
40 /// assert_eq!(true.to_bytes(), [0xb5, 0x75, 0x72, 0x99]);
41 /// assert_eq!(false.to_bytes(), [0x37, 0x97, 0x79, 0xbc]);
42 /// ```
43 #[allow(clippy::unreadable_literal)]
44 fn serialize(&self, buf: &mut impl Extend<u8>) {
45 if *self { 0x997275b5u32 } else { 0xbc799737u32 }.serialize(buf)
46 }
47}
48
49impl Serializable for i32 {
50 /// Serializes the 32-bit signed integer according to the following
51 /// definition:
52 ///
53 /// * `int ? = Int;`.
54 ///
55 /// # Examples
56 ///
57 /// ```
58 /// use grammers_tl_types::Serializable;
59 ///
60 /// assert_eq!(0i32.to_bytes(), [0x00, 0x00, 0x00, 0x00]);
61 /// assert_eq!(1i32.to_bytes(), [0x01, 0x00, 0x00, 0x00]);
62 /// assert_eq!((-1i32).to_bytes(), [0xff, 0xff, 0xff, 0xff]);
63 /// assert_eq!(i32::max_value().to_bytes(), [0xff, 0xff, 0xff, 0x7f]);
64 /// assert_eq!(i32::min_value().to_bytes(), [0x00, 0x00, 0x00, 0x80]);
65 /// ```
66 fn serialize(&self, buf: &mut impl Extend<u8>) {
67 buf.extend(self.to_le_bytes().iter().copied())
68 }
69}
70
71impl Serializable for u32 {
72 /// Serializes the 32-bit unsigned integer according to the following
73 /// definition:
74 ///
75 /// * `int ? = Int;`.
76 ///
77 /// # Examples
78 ///
79 /// ```
80 /// use grammers_tl_types::Serializable;
81 ///
82 /// assert_eq!(0u32.to_bytes(), [0x00, 0x00, 0x00, 0x00]);
83 /// assert_eq!(1u32.to_bytes(), [0x01, 0x00, 0x00, 0x00]);
84 /// assert_eq!(u32::max_value().to_bytes(), [0xff, 0xff, 0xff, 0xff]);
85 /// assert_eq!(u32::min_value().to_bytes(), [0x00, 0x00, 0x00, 0x00]);
86 /// ```
87 fn serialize(&self, buf: &mut impl Extend<u8>) {
88 buf.extend(self.to_le_bytes().iter().copied())
89 }
90}
91
92impl Serializable for i64 {
93 /// Serializes the 64-bit signed integer according to the following
94 /// definition:
95 ///
96 /// * `long ? = Long;`.
97 ///
98 /// # Examples
99 ///
100 /// ```
101 /// use grammers_tl_types::Serializable;
102 ///
103 /// assert_eq!(0i64.to_bytes(), [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);
104 /// assert_eq!(1i64.to_bytes(), [0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);
105 /// assert_eq!((-1i64).to_bytes(), [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
106 /// assert_eq!(i64::max_value().to_bytes(), [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f]);
107 /// assert_eq!(i64::min_value().to_bytes(), [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80]);
108 /// ```
109 fn serialize(&self, buf: &mut impl Extend<u8>) {
110 buf.extend(self.to_le_bytes().iter().copied())
111 }
112}
113
114impl Serializable for [u8; 16] {
115 /// Serializes the 128-bit integer according to the following definition:
116 ///
117 /// * `int128 4*[ int ] = Int128;`.
118 ///
119 /// # Examples
120 ///
121 /// ```
122 /// use grammers_tl_types::Serializable;
123 ///
124 /// let data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
125 ///
126 /// assert_eq!(data.to_bytes(), data);
127 /// ```
128 fn serialize(&self, buf: &mut impl Extend<u8>) {
129 buf.extend(self.iter().copied())
130 }
131}
132
133impl Serializable for [u8; 32] {
134 /// Serializes the 128-bit integer according to the following definition:
135 ///
136 /// * `int256 8*[ int ] = Int256;`.
137 ///
138 /// # Examples
139 ///
140 /// ```
141 /// use grammers_tl_types::Serializable;
142 ///
143 /// let data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
144 /// 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32];
145 ///
146 /// assert_eq!(data.to_bytes(), data);
147 /// ```
148 fn serialize(&self, buf: &mut impl Extend<u8>) {
149 buf.extend(self.iter().copied())
150 }
151}
152
153impl Serializable for f64 {
154 /// Serializes the 64-bit floating point according to the following
155 /// definition:
156 ///
157 /// * `double ? = Double;`.
158 ///
159 /// # Examples
160 ///
161 /// ```
162 /// use std::f64;
163 /// use grammers_tl_types::Serializable;
164 ///
165 /// assert_eq!(0f64.to_bytes(), [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]);
166 /// assert_eq!(1.5f64.to_bytes(), [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf8, 0x3f]);
167 /// assert_eq!((-1.5f64).to_bytes(), [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf8, 0xbf]);
168 /// assert_eq!(f64::INFINITY.to_bytes(), [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf0, 0x7f]);
169 /// assert_eq!(f64::NEG_INFINITY.to_bytes(), [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf0, 0xff]);
170 /// ```
171 fn serialize(&self, buf: &mut impl Extend<u8>) {
172 buf.extend(self.to_le_bytes().iter().copied())
173 }
174}
175
176impl<T: Serializable> Serializable for Vec<T> {
177 /// Serializes a vector of serializable items according to the following
178 /// definition:
179 ///
180 /// * `vector#1cb5c415 {t:Type} # [ t ] = Vector t;`.
181 ///
182 /// # Examples
183 ///
184 /// ```
185 /// use grammers_tl_types::Serializable;
186 ///
187 /// assert_eq!(Vec::<i32>::new().to_bytes(), [0x15, 0xc4, 0xb5, 0x1c, 0x0, 0x0, 0x0, 0x0]);
188 /// assert_eq!(vec![0x7f_i32].to_bytes(),
189 /// [0x15, 0xc4, 0xb5, 0x1c, 0x1, 0x0, 0x0, 0x0, 0x7f, 0x0, 0x0, 0x0]);
190 /// ```
191 #[allow(clippy::unreadable_literal)]
192 fn serialize(&self, buf: &mut impl Extend<u8>) {
193 0x1cb5c415u32.serialize(buf);
194 (self.len() as i32).serialize(buf);
195 self.iter().for_each(|x| x.serialize(buf));
196 }
197}
198
199impl<T: Serializable> Serializable for crate::RawVec<T> {
200 /// Serializes a raw vector of serializable items according to the following
201 /// definition:
202 ///
203 /// * `vector#1cb5c415 {t:Type} # [ t ] = Vector t;`.
204 ///
205 /// # Examples
206 ///
207 /// ```
208 /// use grammers_tl_types::{RawVec, Serializable};
209 ///
210 /// assert_eq!(RawVec(Vec::<i32>::new()).to_bytes(), [0x0, 0x0, 0x0, 0x0]);
211 /// assert_eq!(RawVec(vec![0x7f_i32]).to_bytes(), [0x1, 0x0, 0x0, 0x0, 0x7f, 0x0, 0x0, 0x0]);
212 /// ```
213 fn serialize(&self, buf: &mut impl Extend<u8>) {
214 (self.0.len() as i32).serialize(buf);
215 self.0.iter().for_each(|x| x.serialize(buf));
216 }
217}
218
219impl Serializable for String {
220 /// Serializes a UTF-8 string according to the following definition:
221 ///
222 /// * `string ? = String;`.
223 ///
224 /// # Examples
225 ///
226 /// ```
227 /// use grammers_tl_types::Serializable;
228 ///
229 /// fn test_string(string: &str, prefix: &[u8], suffix: &[u8]) {
230 /// let bytes = string.to_owned().to_bytes();
231 /// let expected = {
232 /// let mut tmp = prefix.to_vec();
233 /// tmp.extend(string.as_bytes());
234 /// tmp.extend(suffix);
235 /// tmp
236 /// };
237 ///
238 /// assert_eq!(bytes, expected);
239 /// }
240 ///
241 /// test_string("", &[0x00], &[0x00, 0x00, 0x00]);
242 /// test_string("Hi", &[0x02], &[0x0]);
243 /// test_string("Hi!", &[0x03], &[]);
244 /// test_string("Hello", &[0x05], &[0x0, 0x0]);
245 /// test_string("Hello, world!", &[0xd], &[0x0, 0x0]);
246 /// test_string(
247 /// "This is a very long string, and it has to be longer than 253 \
248 /// characters, which are quite a few but we can make it! Although, \
249 /// it is quite challenging. The quick brown fox jumps over the lazy \
250 /// fox. There is still some more text we need to type. Oh, this \
251 /// sentence made it past!",
252 /// &[0xfe, 0x11, 0x01, 0x00],
253 /// &[0x00, 0x00, 0x00]
254 /// );
255 /// ```
256 fn serialize(&self, buf: &mut impl Extend<u8>) {
257 self.as_bytes().serialize(buf)
258 }
259}
260
261impl Serializable for Vec<u8> {
262 /// Serializes a vector of bytes as a byte-string according to the following
263 /// definition:
264 ///
265 /// * `string ? = String;`.
266 ///
267 /// # Examples
268 ///
269 /// ```
270 /// use grammers_tl_types::Serializable;
271 ///
272 /// assert_eq!(Vec::<u8>::new().to_bytes(), &[0x00, 0x00, 0x00, 0x00]);
273 /// assert_eq!(vec![0x7f_u8].to_bytes(), &[0x01, 0x7f, 0x00, 0x00]);
274 /// ```
275 fn serialize(&self, buf: &mut impl Extend<u8>) {
276 (&self[..]).serialize(buf)
277 }
278}
279
280impl Serializable for &[u8] {
281 /// Serializes a byte-string according to the following definition:
282 ///
283 /// * `string ? = String;`.
284 ///
285 /// # Examples
286 ///
287 /// ```
288 /// use grammers_tl_types::Serializable;
289 ///
290 /// assert_eq!((&[0x7f_u8][..]).to_bytes(), &[0x01, 0x7f, 0x00, 0x00]);
291 /// ```
292 fn serialize(&self, buf: &mut impl Extend<u8>) {
293 let len = if self.len() <= 253 {
294 buf.extend([self.len() as u8]);
295 self.len() + 1
296 } else {
297 buf.extend([
298 254,
299 (self.len() & 0xff) as u8,
300 ((self.len() >> 8) & 0xff) as u8,
301 ((self.len() >> 16) & 0xff) as u8,
302 ]);
303 self.len()
304 };
305 let padding = (4 - (len % 4)) % 4;
306
307 buf.extend(self.iter().copied());
308 buf.extend((0..padding).map(|_| 0));
309 }
310}