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}