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