grammers_tl_types/deserialize.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//! Types and traits involving the deserialization of the generated objects.
10use std::fmt;
11
12/// Errors that can be produced by [`Cursor`].
13#[derive(Clone, Debug, PartialEq)]
14pub enum Error {
15 /// The end of the buffer was reached earlier than anticipated, which
16 /// implies there is not enough data to complete the deserialization.
17 UnexpectedEof,
18
19 /// The error type indicating an unexpected constructor was found,
20 /// for example, when reading data that doesn't represent the
21 /// correct type (e.g. reading a `bool` when we expect a `Vec`).
22 /// In particular, it can occur in the following situations:
23 ///
24 /// * When reading a boolean.
25 /// * When reading a boxed vector.
26 /// * When reading an arbitrary boxed type.
27 ///
28 /// It is important to note that unboxed or bare [`types`] lack the
29 /// constructor information, and as such they cannot be validated.
30 ///
31 /// [`types`]: types/index.html
32 UnexpectedConstructor {
33 /// The unexpected constructor identifier.
34 id: u32,
35 },
36}
37
38impl std::error::Error for Error {}
39
40impl fmt::Display for Error {
41 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42 match *self {
43 Self::UnexpectedEof => write!(f, "unexpected eof"),
44 Self::UnexpectedConstructor { id } => write!(f, "unexpected constructor: {id:08x}"),
45 }
46 }
47}
48
49/// Re-implementation of [`std::io::Cursor`] to only work over in-memory buffers and greatly
50/// narrow the possible error cases.
51pub struct Cursor<'a> {
52 buf: &'a [u8],
53 pos: usize,
54}
55
56impl<'a> Cursor<'a> {
57 /// Constructors a cursor from a slice of bytes.
58 pub fn from_slice(buf: &'a [u8]) -> Self {
59 Self { buf, pos: 0 }
60 }
61
62 // TODO not a fan we need to expose this (and a way to create `Cursor`),
63 // but crypto needs it because it needs to know where deserialization
64 // of some inner data ends.
65 /// Returns the cursor's position into the slice buffer.
66 pub fn pos(&self) -> usize {
67 self.pos
68 }
69
70 /// Reads a single byte from the slice buffer.
71 pub fn read_byte(&mut self) -> Result<u8> {
72 if self.pos < self.buf.len() {
73 let byte = self.buf[self.pos];
74 self.pos += 1;
75 Ok(byte)
76 } else {
77 Err(Error::UnexpectedEof)
78 }
79 }
80
81 /// Reads an exact amount of bytes to fill the input buffer.
82 pub fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
83 if self.pos + buf.len() > self.buf.len() {
84 Err(Error::UnexpectedEof)
85 } else {
86 buf.copy_from_slice(&self.buf[self.pos..self.pos + buf.len()]);
87 self.pos += buf.len();
88 Ok(())
89 }
90 }
91
92 /// Reads all the way to the end of the slice buffer.
93 pub fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {
94 buf.extend(&self.buf[self.pos..]);
95 let old = self.pos;
96 self.pos = self.buf.len();
97 Ok(self.pos - old)
98 }
99}
100
101/// Alias over a mutable reference to a [`Cursor`].
102// TODO this is only public for session
103pub type Buffer<'a, 'b> = &'a mut Cursor<'b>;
104
105/// A specialized `Result` type for deserialization operations.
106pub type Result<T> = std::result::Result<T, Error>;
107
108/// This trait allows for data serialized according to the
109/// [Binary Data Serialization] to be deserialized into concrete instances.
110///
111/// [Binary Data Serialization]: https://core.telegram.org/mtproto/serialize
112pub trait Deserializable {
113 /// Deserializes an instance of the type from a given buffer.
114 fn deserialize(buf: Buffer) -> Result<Self>
115 where
116 Self: std::marker::Sized;
117
118 /// Convenience function to deserialize an instance from a slice of bytes.
119 ///
120 /// # Examples
121 ///
122 /// ```
123 /// use grammers_tl_types::Deserializable;
124 ///
125 /// assert_eq!(bool::from_bytes(&[0x37, 0x97, 0x79, 0xbc]).unwrap(), false);
126 /// ```
127 fn from_bytes(buf: &[u8]) -> Result<Self>
128 where
129 Self: std::marker::Sized,
130 {
131 Self::deserialize(&mut Cursor::from_slice(buf))
132 }
133}
134
135impl Deserializable for bool {
136 /// Deserializes a boolean according to the following definitions:
137 ///
138 /// * `boolFalse#bc799737 = Bool;` deserializes into `false`.
139 /// * `boolTrue#997275b5 = Bool;` deserializes into `true`.
140 ///
141 /// # Examples
142 ///
143 /// ```
144 /// use grammers_tl_types::Deserializable;
145 ///
146 /// assert_eq!(bool::from_bytes(&[0xb5, 0x75, 0x72, 0x99]).unwrap(), true);
147 /// assert_eq!(bool::from_bytes(&[0x37, 0x97, 0x79, 0xbc]).unwrap(), false);
148 /// ```
149 #[allow(clippy::unreadable_literal)]
150 fn deserialize(buf: Buffer) -> Result<Self> {
151 let id = u32::deserialize(buf)?;
152 match id {
153 0x997275b5u32 => Ok(true),
154 0xbc799737u32 => Ok(false),
155 _ => Err(Error::UnexpectedConstructor { id }),
156 }
157 }
158}
159
160impl Deserializable for i32 {
161 /// Deserializes a 32-bit signed integer according to the following
162 /// definition:
163 ///
164 /// * `int ? = Int;`.
165 ///
166 /// # Examples
167 ///
168 /// ```
169 /// use grammers_tl_types::Deserializable;
170 ///
171 /// assert_eq!(i32::from_bytes(&[0x00, 0x00, 0x00, 0x00]).unwrap(), 0i32);
172 /// assert_eq!(i32::from_bytes(&[0x01, 0x00, 0x00, 0x00]).unwrap(), 1i32);
173 /// assert_eq!(i32::from_bytes(&[0xff, 0xff, 0xff, 0xff]).unwrap(), -1i32);
174 /// assert_eq!(i32::from_bytes(&[0xff, 0xff, 0xff, 0x7f]).unwrap(), i32::max_value());
175 /// assert_eq!(i32::from_bytes(&[0x00, 0x00, 0x00, 0x80]).unwrap(), i32::min_value());
176 /// ```
177 fn deserialize(buf: Buffer) -> Result<Self> {
178 let mut buffer = [0u8; 4];
179 buf.read_exact(&mut buffer)?;
180 Ok(Self::from_le_bytes(buffer))
181 }
182}
183
184impl Deserializable for u32 {
185 /// Deserializes a 32-bit unsigned integer according to the following
186 /// definition:
187 ///
188 /// * `int ? = Int;`.
189 ///
190 /// # Examples
191 ///
192 /// ```
193 /// use grammers_tl_types::Deserializable;
194 ///
195 /// assert_eq!(u32::from_bytes(&[0x00, 0x00, 0x00, 0x00]).unwrap(), 0u32);
196 /// assert_eq!(u32::from_bytes(&[0x01, 0x00, 0x00, 0x00]).unwrap(), 1u32);
197 /// assert_eq!(u32::from_bytes(&[0xff, 0xff, 0xff, 0xff]).unwrap(), u32::max_value());
198 /// assert_eq!(u32::from_bytes(&[0x00, 0x00, 0x00, 0x00]).unwrap(), u32::min_value());
199 /// ```
200 fn deserialize(buf: Buffer) -> Result<Self> {
201 let mut buffer = [0u8; 4];
202 buf.read_exact(&mut buffer)?;
203 Ok(Self::from_le_bytes(buffer))
204 }
205}
206
207impl Deserializable for i64 {
208 /// Deserializes a 64-bit signed integer according to the following
209 /// definition:
210 ///
211 /// * `long ? = Long;`.
212 ///
213 /// # Examples
214 ///
215 /// ```
216 /// use grammers_tl_types::Deserializable;
217 ///
218 /// assert_eq!(i64::from_bytes(&[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]).unwrap(), 0i64);
219 /// assert_eq!(i64::from_bytes(&[0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]).unwrap(), 1i64);
220 /// assert_eq!(i64::from_bytes(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]).unwrap(), (-1i64));
221 /// assert_eq!(i64::from_bytes(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f]).unwrap(), i64::max_value());
222 /// assert_eq!(i64::from_bytes(&[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80]).unwrap(), i64::min_value());
223 /// ```
224 fn deserialize(buf: Buffer) -> Result<Self> {
225 let mut buffer = [0u8; 8];
226 buf.read_exact(&mut buffer)?;
227 Ok(Self::from_le_bytes(buffer))
228 }
229}
230
231impl Deserializable for [u8; 16] {
232 /// Deserializes the 128-bit integer according to the following
233 /// definition:
234 ///
235 /// * `int128 4*[ int ] = Int128;`.
236 ///
237 /// # Examples
238 ///
239 /// ```
240 /// use grammers_tl_types::Deserializable;
241 ///
242 /// let data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
243 ///
244 /// assert_eq!(<[u8; 16]>::from_bytes(&data).unwrap(), data);
245 /// ```
246 fn deserialize(buf: Buffer) -> Result<Self> {
247 let mut buffer = [0u8; 16];
248 buf.read_exact(&mut buffer)?;
249 Ok(buffer)
250 }
251}
252
253impl Deserializable for [u8; 32] {
254 /// Deserializes the 128-bit integer according to the following
255 /// definition:
256 ///
257 /// * `int256 8*[ int ] = Int256;`.
258 ///
259 /// # Examples
260 ///
261 /// ```
262 /// use grammers_tl_types::Deserializable;
263 ///
264 /// let data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
265 /// 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32];
266 ///
267 /// assert_eq!(<[u8; 32]>::from_bytes(&data).unwrap(), data);
268 /// ```
269 fn deserialize(buf: Buffer) -> Result<Self> {
270 let mut buffer = [0u8; 32];
271 buf.read_exact(&mut buffer)?;
272 Ok(buffer)
273 }
274}
275
276impl Deserializable for f64 {
277 /// Deserializes a 64-bit floating point according to the
278 /// following definition:
279 ///
280 /// * `double ? = Double;`.
281 ///
282 /// # Examples
283 ///
284 /// ```
285 /// use std::f64;
286 /// use grammers_tl_types::Deserializable;
287 ///
288 /// assert_eq!(f64::from_bytes(&[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0]).unwrap(), 0f64);
289 /// assert_eq!(f64::from_bytes(&[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf8, 0x3f]).unwrap(), 1.5f64);
290 /// assert_eq!(f64::from_bytes(&[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf8, 0xbf]).unwrap(), -1.5f64);
291 /// assert_eq!(f64::from_bytes(&[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf0, 0x7f]).unwrap(), f64::INFINITY);
292 /// assert_eq!(f64::from_bytes(&[0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf0, 0xff]).unwrap(), f64::NEG_INFINITY);
293 /// ```
294 fn deserialize(buf: Buffer) -> Result<Self> {
295 let mut buffer = [0u8; 8];
296 buf.read_exact(&mut buffer)?;
297 Ok(Self::from_le_bytes(buffer))
298 }
299}
300
301impl<T: Deserializable> Deserializable for Vec<T> {
302 /// Deserializes a vector of deserializable items according to the
303 /// following definition:
304 ///
305 /// * `vector#1cb5c415 {t:Type} # [ t ] = Vector t;`.
306 ///
307 /// # Examples
308 ///
309 /// ```
310 /// use grammers_tl_types::Deserializable;
311 ///
312 /// assert_eq!(Vec::<i32>::from_bytes(&[0x15, 0xc4, 0xb5, 0x1c, 0x0, 0x0, 0x0, 0x0]).unwrap(), Vec::new());
313 /// assert_eq!(Vec::<i32>::from_bytes(&[0x15, 0xc4, 0xb5, 0x1c, 0x1, 0x0, 0x0, 0x0, 0x7f, 0x0, 0x0, 0x0]).unwrap(),
314 /// vec![0x7f_i32]);
315 /// ```
316 #[allow(clippy::unreadable_literal)]
317 fn deserialize(buf: Buffer) -> Result<Self> {
318 let id = u32::deserialize(buf)?;
319 if id != 0x1cb5c415u32 {
320 return Err(Error::UnexpectedConstructor { id });
321 }
322 let len = u32::deserialize(buf)?;
323 (0..len).map(|_| T::deserialize(buf)).collect()
324 }
325}
326
327impl<T: Deserializable> Deserializable for crate::RawVec<T> {
328 /// Deserializes a vector of deserializable items according to the
329 /// following definition:
330 ///
331 /// * `vector#1cb5c415 {t:Type} # [ t ] = Vector t;`.
332 ///
333 /// # Examples
334 ///
335 /// ```
336 /// use grammers_tl_types::{RawVec, Deserializable};
337 ///
338 /// assert_eq!(RawVec::<i32>::from_bytes(&[0x0, 0x0, 0x0, 0x0]).unwrap().0, Vec::<i32>::new());
339 /// assert_eq!(RawVec::<i32>::from_bytes(&[0x1, 0x0, 0x0, 0x0, 0x7f, 0x0, 0x0, 0x0]).unwrap().0, vec![0x7f_i32]);
340 /// ```
341 fn deserialize(buf: Buffer) -> Result<Self> {
342 let len = u32::deserialize(buf)?;
343 Ok(Self(
344 (0..len)
345 .map(|_| T::deserialize(buf))
346 .collect::<Result<Vec<T>>>()?,
347 ))
348 }
349}
350
351impl Deserializable for String {
352 /// Deserializes a UTF-8 string according to the following definition:
353 ///
354 /// * `string ? = String;`.
355 ///
356 /// # Examples
357 ///
358 /// ```
359 /// use grammers_tl_types::Deserializable;
360 ///
361 /// fn test_string(string: &str, prefix: &[u8], suffix: &[u8]) {
362 /// let bytes = {
363 /// let mut tmp = prefix.to_vec();
364 /// tmp.extend(string.as_bytes());
365 /// tmp.extend(suffix);
366 /// tmp
367 /// };
368 /// let expected = string.to_owned();
369 ///
370 /// assert_eq!(String::from_bytes(&bytes).unwrap(), expected);
371 /// }
372 ///
373 /// test_string("", &[0x00], &[0x00, 0x00, 0x00]);
374 /// test_string("Hi", &[0x02], &[0x0]);
375 /// test_string("Hi!", &[0x03], &[]);
376 /// test_string("Hello", &[0x05], &[0x0, 0x0]);
377 /// test_string("Hello, world!", &[0xd], &[0x0, 0x0]);
378 /// test_string(
379 /// "This is a very long string, and it has to be longer than 253 \
380 /// characters, which are quite a few but we can make it! Although, \
381 /// it is quite challenging. The quick brown fox jumps over the lazy \
382 /// fox. There is still some more text we need to type. Oh, this \
383 /// sentence made it past!",
384 /// &[0xfe, 0x11, 0x01, 0x00],
385 /// &[0x00, 0x00, 0x00]
386 /// );
387 /// ```
388 fn deserialize(buf: Buffer) -> Result<Self> {
389 Ok(String::from_utf8_lossy(&Vec::<u8>::deserialize(buf)?).into())
390 }
391}
392
393impl Deserializable for Vec<u8> {
394 /// Deserializes a vector of bytes as a byte-string according to the
395 /// following definition:
396 ///
397 /// * `string ? = String;`.
398 ///
399 /// # Examples
400 ///
401 /// ```
402 /// use grammers_tl_types::{Deserializable};
403 ///
404 /// assert_eq!(Vec::<u8>::from_bytes(&[0x00, 0x00, 0x00, 0x00]).unwrap(), Vec::new());
405 /// assert_eq!(Vec::<u8>::from_bytes(&[0x01, 0x7f, 0x00, 0x00]).unwrap(), vec![0x7f_u8]);
406 /// ```
407 fn deserialize(buf: Buffer) -> Result<Self> {
408 let first_byte = buf.read_byte()?;
409 let (len, padding) = if first_byte == 254 {
410 let mut buffer = [0u8; 3];
411 buf.read_exact(&mut buffer)?;
412 let len =
413 (buffer[0] as usize) | ((buffer[1] as usize) << 8) | ((buffer[2] as usize) << 16);
414
415 (len, len % 4)
416 } else {
417 let len = first_byte as usize;
418 (len, (len + 1) % 4)
419 };
420
421 let mut result = vec![0u8; len];
422 buf.read_exact(&mut result)?;
423
424 if padding > 0 {
425 for _ in 0..(4 - padding) {
426 buf.read_byte()?;
427 }
428 }
429
430 Ok(result)
431 }
432}