tl_proto/
boxed.rs

1use crate::traits::*;
2
3/// Marks bare type with the appropriate constructor id.
4pub trait BoxedConstructor: Sized {
5    /// Constructor id.
6    const TL_ID: u32;
7
8    /// Wraps bare type reference into `BoxedWrapper`.
9    fn as_boxed(&self) -> BoxedWrapper<&Self> {
10        BoxedWrapper(self)
11    }
12
13    /// Converts bare type into `BoxedWrapper`.
14    fn into_boxed(self) -> BoxedWrapper<Self> {
15        BoxedWrapper(self)
16    }
17}
18
19impl<T> BoxedConstructor for &T
20where
21    T: BoxedConstructor,
22{
23    const TL_ID: u32 = T::TL_ID;
24}
25
26/// Simple helper which contains inner value and constructor id.
27///
28/// Used mostly for serialization, so can contain references.
29#[derive(Debug, Clone)]
30pub struct BoxedWrapper<T>(pub T);
31
32impl<T> TlWrite for BoxedWrapper<T>
33where
34    T: BoxedConstructor + TlWrite<Repr = Bare>,
35{
36    type Repr = Boxed;
37
38    #[inline(always)]
39    fn max_size_hint(&self) -> usize {
40        4 + self.0.max_size_hint()
41    }
42
43    #[inline(always)]
44    fn write_to<P>(&self, packet: &mut P)
45    where
46        P: TlPacket,
47    {
48        T::TL_ID.write_to(packet);
49        self.0.write_to(packet);
50    }
51}
52
53impl<'a, T> TlRead<'a> for BoxedWrapper<T>
54where
55    T: BoxedConstructor + TlRead<'a, Repr = Bare>,
56{
57    type Repr = Boxed;
58
59    fn read_from(packet: &mut &'a [u8]) -> TlResult<Self> {
60        match u32::read_from(packet) {
61            Ok(id) if id == T::TL_ID => match T::read_from(packet) {
62                Ok(data) => Ok(BoxedWrapper(data)),
63                Err(e) => Err(e),
64            },
65            Ok(_) => Err(TlError::UnknownConstructor),
66            Err(e) => Err(e),
67        }
68    }
69}