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}