ferogram_tl_types/
deserialize.rs1use std::fmt;
14use std::sync::OnceLock;
15
16pub fn tl_debug() -> bool {
25 static ENABLED: OnceLock<bool> = OnceLock::new();
26 *ENABLED.get_or_init(|| std::env::var("FEROGRAM_TL_DEBUG").is_ok_and(|v| !v.is_empty()))
27}
28
29#[derive(Clone, Debug, PartialEq)]
31pub enum Error {
32 UnexpectedEof,
34 UnexpectedConstructor { id: u32 },
36}
37
38impl fmt::Display for Error {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 match self {
41 Self::UnexpectedEof => write!(f, "unexpected end of buffer"),
42 Self::UnexpectedConstructor { id } => {
43 write!(f, "unexpected constructor id: {id:#010x}")
44 }
45 }
46 }
47}
48
49impl std::error::Error for Error {}
50
51pub type Result<T> = std::result::Result<T, Error>;
53
54pub struct Cursor<'a> {
61 buf: &'a [u8],
62 pos: usize,
63}
64
65impl<'a> Cursor<'a> {
66 pub fn from_slice(buf: &'a [u8]) -> Self {
68 Self { buf, pos: 0 }
69 }
70
71 pub fn pos(&self) -> usize {
73 self.pos
74 }
75
76 pub fn remaining(&self) -> usize {
78 self.buf.len() - self.pos
79 }
80
81 pub fn read_byte(&mut self) -> Result<u8> {
83 match self.buf.get(self.pos).copied() {
84 Some(b) => {
85 self.pos += 1;
86 Ok(b)
87 }
88 None => Err(Error::UnexpectedEof),
89 }
90 }
91
92 pub fn read_exact(&mut self, out: &mut [u8]) -> Result<()> {
94 let end = self.pos + out.len();
95 if end > self.buf.len() {
96 return Err(Error::UnexpectedEof);
97 }
98 out.copy_from_slice(&self.buf[self.pos..end]);
99 self.pos = end;
100 Ok(())
101 }
102
103 pub fn read_to_end(&mut self, out: &mut Vec<u8>) -> usize {
105 let slice = &self.buf[self.pos..];
106 out.extend_from_slice(slice);
107 self.pos = self.buf.len();
108 slice.len()
109 }
110}
111
112pub type Buffer<'a, 'b> = &'a mut Cursor<'b>;
114
115pub trait Deserializable: Sized {
119 fn deserialize(buf: Buffer) -> Result<Self>;
121
122 fn from_bytes(bytes: &[u8]) -> Result<Self> {
124 let mut cursor = Cursor::from_slice(bytes);
125 Self::deserialize(&mut cursor)
126 }
127
128 fn from_bytes_exact(bytes: &[u8]) -> Result<Self> {
134 let mut cursor = Cursor::from_slice(bytes);
135 let value = Self::deserialize(&mut cursor)?;
136 Ok(value)
139 }
140}
141
142impl Deserializable for bool {
145 fn deserialize(buf: Buffer) -> Result<Self> {
146 match u32::deserialize(buf)? {
147 0x997275b5 => Ok(true),
148 0xbc799737 => Ok(false),
149 id => Err(Error::UnexpectedConstructor { id }),
150 }
151 }
152}
153
154impl Deserializable for i32 {
155 fn deserialize(buf: Buffer) -> Result<Self> {
156 let mut b = [0u8; 4];
157 buf.read_exact(&mut b)?;
158 Ok(i32::from_le_bytes(b))
159 }
160}
161
162impl Deserializable for u32 {
163 fn deserialize(buf: Buffer) -> Result<Self> {
164 let mut b = [0u8; 4];
165 buf.read_exact(&mut b)?;
166 Ok(u32::from_le_bytes(b))
167 }
168}
169
170impl Deserializable for i64 {
171 fn deserialize(buf: Buffer) -> Result<Self> {
172 let mut b = [0u8; 8];
173 buf.read_exact(&mut b)?;
174 Ok(i64::from_le_bytes(b))
175 }
176}
177
178impl Deserializable for f64 {
179 fn deserialize(buf: Buffer) -> Result<Self> {
180 let mut b = [0u8; 8];
181 buf.read_exact(&mut b)?;
182 Ok(f64::from_le_bytes(b))
183 }
184}
185
186impl Deserializable for [u8; 16] {
187 fn deserialize(buf: Buffer) -> Result<Self> {
188 let mut b = [0u8; 16];
189 buf.read_exact(&mut b)?;
190 Ok(b)
191 }
192}
193
194impl Deserializable for [u8; 32] {
195 fn deserialize(buf: Buffer) -> Result<Self> {
196 let mut b = [0u8; 32];
197 buf.read_exact(&mut b)?;
198 Ok(b)
199 }
200}
201
202impl Deserializable for Vec<u8> {
205 fn deserialize(buf: Buffer) -> Result<Self> {
206 let first = buf.read_byte()?;
207 let (len, header_extra) = if first != 0xfe {
208 (first as usize, 0)
209 } else {
210 let a = buf.read_byte()? as usize;
211 let b = buf.read_byte()? as usize;
212 let c = buf.read_byte()? as usize;
213 (a | (b << 8) | (c << 16), 3)
214 };
215
216 let mut data = vec![0u8; len];
217 buf.read_exact(&mut data)?;
218
219 let total = 1 + header_extra + len;
221 let padding = (4 - (total % 4)) % 4;
222 for _ in 0..padding {
223 buf.read_byte()?;
224 }
225
226 Ok(data)
227 }
228}
229
230impl Deserializable for String {
231 fn deserialize(buf: Buffer) -> Result<Self> {
232 let bytes = Vec::<u8>::deserialize(buf)?;
233 String::from_utf8(bytes).map_err(|_| Error::UnexpectedEof)
234 }
235}
236
237impl<T: Deserializable> Deserializable for Vec<T> {
240 fn deserialize(buf: Buffer) -> Result<Self> {
241 let id = u32::deserialize(buf)?;
242 if id != 0x1cb5c415 {
243 return Err(Error::UnexpectedConstructor { id });
244 }
245 let len = i32::deserialize(buf)? as usize;
246 (0..len).map(|_| T::deserialize(buf)).collect()
247 }
248}
249
250impl<T: Deserializable> Deserializable for crate::RawVec<T> {
251 fn deserialize(buf: Buffer) -> Result<Self> {
252 let len = i32::deserialize(buf)? as usize;
253 let inner = (0..len)
254 .map(|_| T::deserialize(buf))
255 .collect::<Result<_>>()?;
256 Ok(crate::RawVec(inner))
257 }
258}