tl_types/
serialize.rs

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