Skip to main content

layer_tl_types/
deserialize.rs

1//! The [`Deserializable`] trait, [`Cursor`] buffer, and primitive impls.
2
3use std::fmt;
4
5// ─── Error ───────────────────────────────────────────────────────────────────
6
7/// Errors that can occur during deserialization.
8#[derive(Clone, Debug, PartialEq)]
9pub enum Error {
10    /// Ran out of bytes before the type was fully read.
11    UnexpectedEof,
12    /// Decoded a constructor ID that doesn't match any known variant.
13    UnexpectedConstructor { id: u32 },
14}
15
16impl fmt::Display for Error {
17    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18        match self {
19            Self::UnexpectedEof => write!(f, "unexpected end of buffer"),
20            Self::UnexpectedConstructor { id } => {
21                write!(f, "unexpected constructor id: {id:#010x}")
22            }
23        }
24    }
25}
26
27impl std::error::Error for Error {}
28
29/// Specialized `Result` for deserialization.
30pub type Result<T> = std::result::Result<T, Error>;
31
32// ─── Cursor ──────────────────────────────────────────────────────────────────
33
34/// A zero-copy cursor over an in-memory byte slice.
35///
36/// Avoids `std::io::Cursor` and its wide error surface; only the two error
37/// cases above can ever occur during TL deserialization.
38pub struct Cursor<'a> {
39    buf: &'a [u8],
40    pos: usize,
41}
42
43impl<'a> Cursor<'a> {
44    /// Create a cursor positioned at the start of `buf`.
45    pub fn from_slice(buf: &'a [u8]) -> Self {
46        Self { buf, pos: 0 }
47    }
48
49    /// Current byte offset.
50    pub fn pos(&self) -> usize { self.pos }
51
52    /// Remaining bytes.
53    pub fn remaining(&self) -> usize { self.buf.len() - self.pos }
54
55    /// Read a single byte.
56    pub fn read_byte(&mut self) -> Result<u8> {
57        match self.buf.get(self.pos).copied() {
58            Some(b) => { self.pos += 1; Ok(b) }
59            None    => Err(Error::UnexpectedEof),
60        }
61    }
62
63    /// Read exactly `buf.len()` bytes.
64    pub fn read_exact(&mut self, out: &mut [u8]) -> Result<()> {
65        let end = self.pos + out.len();
66        if end > self.buf.len() {
67            return Err(Error::UnexpectedEof);
68        }
69        out.copy_from_slice(&self.buf[self.pos..end]);
70        self.pos = end;
71        Ok(())
72    }
73
74    /// Consume all remaining bytes into `out`.
75    pub fn read_to_end(&mut self, out: &mut Vec<u8>) -> usize {
76        let slice = &self.buf[self.pos..];
77        out.extend_from_slice(slice);
78        self.pos = self.buf.len();
79        slice.len()
80    }
81}
82
83/// Alias used by generated code: `crate::deserialize::Buffer<'_, '_>`.
84pub type Buffer<'a, 'b> = &'a mut Cursor<'b>;
85
86// ─── Deserializable ──────────────────────────────────────────────────────────
87
88/// Deserialize a value from TL binary format.
89pub trait Deserializable: Sized {
90    /// Read `Self` from `buf`, advancing its position.
91    fn deserialize(buf: Buffer) -> Result<Self>;
92
93    /// Convenience: deserialize from a byte slice.
94    fn from_bytes(bytes: &[u8]) -> Result<Self> {
95        let mut cursor = Cursor::from_slice(bytes);
96        Self::deserialize(&mut cursor)
97    }
98}
99
100// ─── Primitives ───────────────────────────────────────────────────────────────
101
102impl Deserializable for bool {
103    fn deserialize(buf: Buffer) -> Result<Self> {
104        match u32::deserialize(buf)? {
105            0x997275b5 => Ok(true),
106            0xbc799737 => Ok(false),
107            id => Err(Error::UnexpectedConstructor { id }),
108        }
109    }
110}
111
112impl Deserializable for i32 {
113    fn deserialize(buf: Buffer) -> Result<Self> {
114        let mut b = [0u8; 4];
115        buf.read_exact(&mut b)?;
116        Ok(i32::from_le_bytes(b))
117    }
118}
119
120impl Deserializable for u32 {
121    fn deserialize(buf: Buffer) -> Result<Self> {
122        let mut b = [0u8; 4];
123        buf.read_exact(&mut b)?;
124        Ok(u32::from_le_bytes(b))
125    }
126}
127
128impl Deserializable for i64 {
129    fn deserialize(buf: Buffer) -> Result<Self> {
130        let mut b = [0u8; 8];
131        buf.read_exact(&mut b)?;
132        Ok(i64::from_le_bytes(b))
133    }
134}
135
136impl Deserializable for f64 {
137    fn deserialize(buf: Buffer) -> Result<Self> {
138        let mut b = [0u8; 8];
139        buf.read_exact(&mut b)?;
140        Ok(f64::from_le_bytes(b))
141    }
142}
143
144impl Deserializable for [u8; 16] {
145    fn deserialize(buf: Buffer) -> Result<Self> {
146        let mut b = [0u8; 16];
147        buf.read_exact(&mut b)?;
148        Ok(b)
149    }
150}
151
152impl Deserializable for [u8; 32] {
153    fn deserialize(buf: Buffer) -> Result<Self> {
154        let mut b = [0u8; 32];
155        buf.read_exact(&mut b)?;
156        Ok(b)
157    }
158}
159
160// ─── Bytes / String ───────────────────────────────────────────────────────────
161
162impl Deserializable for Vec<u8> {
163    fn deserialize(buf: Buffer) -> Result<Self> {
164        let first = buf.read_byte()?;
165        let (len, header_extra) = if first != 0xfe {
166            (first as usize, 0)
167        } else {
168            let a = buf.read_byte()? as usize;
169            let b = buf.read_byte()? as usize;
170            let c = buf.read_byte()? as usize;
171            (a | (b << 8) | (c << 16), 3)
172        };
173
174        let mut data = vec![0u8; len];
175        buf.read_exact(&mut data)?;
176
177        // Skip alignment padding
178        let total = 1 + header_extra + len;
179        let padding = (4 - (total % 4)) % 4;
180        for _ in 0..padding { buf.read_byte()?; }
181
182        Ok(data)
183    }
184}
185
186impl Deserializable for String {
187    fn deserialize(buf: Buffer) -> Result<Self> {
188        let bytes = Vec::<u8>::deserialize(buf)?;
189        String::from_utf8(bytes).map_err(|_| Error::UnexpectedEof)
190    }
191}
192
193// ─── Vectors ─────────────────────────────────────────────────────────────────
194
195impl<T: Deserializable> Deserializable for Vec<T> {
196    fn deserialize(buf: Buffer) -> Result<Self> {
197        let id = u32::deserialize(buf)?;
198        if id != 0x1cb5c415 {
199            return Err(Error::UnexpectedConstructor { id });
200        }
201        let len = i32::deserialize(buf)? as usize;
202        (0..len).map(|_| T::deserialize(buf)).collect()
203    }
204}
205
206impl<T: Deserializable> Deserializable for crate::RawVec<T> {
207    fn deserialize(buf: Buffer) -> Result<Self> {
208        let len = i32::deserialize(buf)? as usize;
209        let inner = (0..len).map(|_| T::deserialize(buf)).collect::<Result<_>>()?;
210        Ok(crate::RawVec(inner))
211    }
212}