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