makepad_micro_serde/
serde_bin.rs

1use std::{
2    collections::HashMap,
3    hash::Hash,
4    convert::TryInto,
5    str,
6};
7
8#[allow(unused_imports)]
9#[cfg(any(target_os = "android", target_os = "linux", target_os="macos", target_os="ios"))]
10use std::{
11    ffi::{OsStr, OsString},
12    path::{PathBuf, Path},
13};
14
15pub trait SerBin {
16    fn serialize_bin(&self)->Vec<u8>{
17        let mut s = Vec::new();
18        self.ser_bin(&mut s);
19        s
20    }
21    
22    fn ser_bin(&self, s: &mut Vec<u8>);
23}
24
25pub trait DeBin:Sized {
26    fn deserialize_bin(d:&[u8])->Result<Self, DeBinErr>{
27        DeBin::de_bin(&mut 0, d)
28    }
29
30    fn de_bin(o:&mut usize, d:&[u8]) -> Result<Self, DeBinErr>;
31}
32
33
34pub struct DeBinErr{
35    pub msg: String,
36    pub o: usize,
37    pub l: usize,
38    pub s: usize
39}
40
41impl std::fmt::Display for DeBinErr {
42    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43        write!(f, "Error deserializing {} ", self.msg)?;
44        if self.l != 0 {
45            write!(f, "while trying to read {} bytes ", self.l)?
46        }
47        write!(f, " at offset {} in buffer of size {}", self.o, self.s)
48    }
49}
50
51impl std::fmt::Debug for DeBinErr {
52    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53        std::fmt::Display::fmt(self, f)
54    }
55}
56
57macro_rules! impl_ser_de_bin_for {
58    ($ty:ident) => {
59        impl SerBin for $ty {
60            fn ser_bin(&self, s: &mut Vec<u8>) {
61                s.extend_from_slice(&self.to_le_bytes());
62            }
63        }
64        
65        impl DeBin for $ty {
66            fn de_bin(o:&mut usize, d:&[u8]) -> Result<$ty, DeBinErr> {
67                let l = std::mem::size_of::<$ty>();
68                if *o + l > d.len(){
69                    return Err(DeBinErr{o:*o, l, s:d.len(), msg:format!("{}", stringify!($ty))})
70                }
71                let ret = $ty::from_le_bytes(d[*o..*o+l].try_into().unwrap());
72                *o += l;
73                Ok(ret)
74            }
75        }
76    };
77}
78
79impl_ser_de_bin_for!(f64);
80impl_ser_de_bin_for!(f32);
81impl_ser_de_bin_for!(u64);
82impl_ser_de_bin_for!(i64);
83impl_ser_de_bin_for!(u32);
84impl_ser_de_bin_for!(i32);
85impl_ser_de_bin_for!(u16);
86impl_ser_de_bin_for!(i16);
87
88impl SerBin for usize {
89    fn ser_bin(&self, s: &mut Vec<u8>) {
90        s.extend_from_slice(&(*self as u64).to_le_bytes());
91    }
92}
93
94impl DeBin for usize {
95    fn de_bin(o:&mut usize, d:&[u8]) -> Result<usize, DeBinErr> {
96        let l = std::mem::size_of::<u64>();
97        if *o + l > d.len(){
98            return Err(DeBinErr{o:*o, l, s:d.len(), msg:"usize".to_string()})
99        }
100        let ret = u64::from_le_bytes(d[*o..*o+l].try_into().unwrap()) as usize;
101        *o += l;
102        Ok(ret)
103    }
104}
105
106impl DeBin for u8 {
107    fn de_bin(o:&mut usize, d:&[u8]) -> Result<u8,DeBinErr> {
108        if *o + 1 > d.len(){
109            return Err(DeBinErr{o:*o, l:1, s:d.len(), msg:"u8".to_string()})
110        } 
111        let m = d[*o];
112        *o += 1;
113        Ok(m)
114    }
115}
116
117impl SerBin for u8 {
118    fn ser_bin(&self, s: &mut Vec<u8>) {
119        s.push(*self);
120    }
121}
122
123impl SerBin for bool {
124    fn ser_bin(&self, s: &mut Vec<u8>) {
125        s.push(if *self {1} else {0});
126    }
127}
128
129impl DeBin for bool {
130    fn de_bin(o:&mut usize, d:&[u8]) -> Result<bool, DeBinErr> {
131        if *o + 1 > d.len(){
132            return Err(DeBinErr{o:*o, l:1, s:d.len(), msg:"bool".to_string()})
133        } 
134        let m = d[*o];
135        *o += 1;
136        if m == 0{Ok(false)} else {Ok(true)}
137    }
138}
139
140impl SerBin for String {
141    fn ser_bin(&self, s: &mut Vec<u8>) {
142        let len = self.len();
143        len.ser_bin(s);
144        s.extend_from_slice(self.as_bytes());
145    }
146}
147
148impl DeBin for String {
149    fn de_bin(o:&mut usize, d:&[u8])->Result<String, DeBinErr> {
150        let len:u64 = DeBin::de_bin(o,d)?;
151        if *o + (len as usize) > d.len(){
152            return Err(DeBinErr{o:*o, l:1, s:d.len(), msg:"String".to_string()})
153        } 
154        let r = std::str::from_utf8(&d[*o..(*o+(len as usize))]).unwrap().to_string();
155        *o += len as usize;
156        Ok(r)
157    }
158}
159
160impl<T> SerBin for Vec<T> where T: SerBin {
161    fn ser_bin(&self, s: &mut Vec<u8>) {
162        let len = self.len() as u64;
163        len.ser_bin(s);
164        for item in self {
165            item.ser_bin(s);
166        }
167    }
168}
169
170impl<T> DeBin for Vec<T> where T:DeBin{
171    fn de_bin(o:&mut usize, d:&[u8])->Result<Vec<T>, DeBinErr> {
172        let len:u64 = DeBin::de_bin(o,d)?;
173        let mut out = Vec::new();
174        for _ in 0..len{
175            out.push(DeBin::de_bin(o,d)?)
176        }
177        Ok(out)
178    }
179}
180
181impl<T> SerBin for Option<T> where T: SerBin {
182    fn ser_bin(&self, s: &mut Vec<u8>) {
183        match self {
184            None => s.push(0),
185            Some(v) => {
186                s.push(1);
187                v.ser_bin(s);
188            }
189        }
190    }
191}
192
193impl<T> DeBin for Option<T> where T:DeBin{
194    fn de_bin(o:&mut usize, d:&[u8])->Result<Option<T>, DeBinErr> {
195        if *o + 1 > d.len(){
196            return Err(DeBinErr{o:*o, l:1, s:d.len(), msg:"Option<T>".to_string()})
197        } 
198        let m = d[*o];
199        *o += 1;
200        Ok(match m {
201            0 => None,
202            1 => Some(DeBin::de_bin(o,d)?),
203            _ => return Err(DeBinErr{o:*o, l:0, s:d.len(), msg:"Option<T>".to_string()}),
204        })
205    }
206}
207
208impl<T, E> SerBin for Result<T, E> where T: SerBin, E: SerBin {
209    fn ser_bin(&self, s: &mut Vec<u8>) {
210        match self {
211            Ok(v) => {
212                s.push(0);
213                v.ser_bin(s);
214            }
215            Err(e) => {
216                s.push(1);
217                e.ser_bin(s);
218            }
219        }
220    }
221}
222
223impl<T, E> DeBin for Result<T, E> where T: DeBin, E: DeBin {
224    fn de_bin(o: &mut usize, d: &[u8]) -> Result<Self, DeBinErr> {
225        if *o + 1 > d.len() {
226            return Err(DeBinErr{o:*o, l:1, s:d.len(), msg:"Result<T, E>".to_string()});
227        }
228        let m = d[*o];
229        *o += 1;
230        Ok(match m {
231            0 => Ok(T::de_bin(o, d)?),
232            1 => Err(E::de_bin(o, d)?),
233            _ => return Err(DeBinErr{o:*o, l:0, s:d.len(), msg:"Result<T, E>".to_string()}),
234        })
235    }
236}
237
238impl<T> SerBin for [T] where T: SerBin {
239    fn ser_bin(&self, s: &mut Vec<u8>) {
240        for item in self {
241            item.ser_bin(s);
242        }
243    }
244}
245
246
247unsafe fn de_bin_array_impl_inner<T>(top: *mut T, count: usize, o:&mut usize, d:&[u8]) -> Result<(), DeBinErr> where T:DeBin{
248    for c in 0..count {
249        top.add(c).write(DeBin::de_bin(o, d) ?);
250    }
251    Ok(())
252}
253
254impl<T, const N: usize> DeBin for [T; N] where T: DeBin {
255    fn de_bin(o:&mut usize, d:&[u8]) -> Result<Self,
256    DeBinErr> {
257        unsafe{
258            let mut to = std::mem::MaybeUninit::<[T; N]>::uninit();
259            let top: *mut T = &mut to as *mut _ as *mut T;
260            de_bin_array_impl_inner(top, N, o, d)?;
261            Ok(to.assume_init())
262        }
263    }
264}
265
266impl<A,B> SerBin for (A,B) where A: SerBin, B:SerBin {
267    fn ser_bin(&self, s: &mut Vec<u8>) {
268        self.0.ser_bin(s);
269        self.1.ser_bin(s);
270    }
271}
272
273impl<A,B> DeBin for (A,B) where A:DeBin, B:DeBin{
274    fn de_bin(o:&mut usize, d:&[u8])->Result<(A,B), DeBinErr> {Ok((DeBin::de_bin(o,d)?,DeBin::de_bin(o,d)?))}
275}
276
277impl<A,B,C> SerBin for (A,B,C) where A: SerBin, B:SerBin, C:SerBin {
278    fn ser_bin(&self, s: &mut Vec<u8>) {
279        self.0.ser_bin(s);
280        self.1.ser_bin(s);
281        self.2.ser_bin(s);
282    } 
283}
284
285impl<A,B,C> DeBin for (A,B,C) where A:DeBin, B:DeBin, C:DeBin{
286    fn de_bin(o:&mut usize, d:&[u8])->Result<(A,B,C), DeBinErr> {Ok((DeBin::de_bin(o,d)?,DeBin::de_bin(o,d)?,DeBin::de_bin(o,d)?))}
287}
288
289impl<A,B,C,D> SerBin for (A,B,C,D) where A: SerBin, B:SerBin, C:SerBin, D:SerBin {
290    fn ser_bin(&self, s: &mut Vec<u8>) {
291        self.0.ser_bin(s);
292        self.1.ser_bin(s);
293        self.2.ser_bin(s);
294        self.3.ser_bin(s);
295    }
296}
297
298impl<A,B,C,D> DeBin for (A,B,C,D) where A:DeBin, B:DeBin, C:DeBin, D:DeBin{
299    fn de_bin(o:&mut usize, d:&[u8])->Result<(A,B,C,D), DeBinErr> {Ok((DeBin::de_bin(o,d)?,DeBin::de_bin(o,d)?,DeBin::de_bin(o,d)?,DeBin::de_bin(o,d)?))}
300}
301
302impl<K, V> SerBin for HashMap<K, V> where K: SerBin,
303V: SerBin {
304    fn ser_bin(&self, s: &mut Vec<u8>) {
305        let len = self.len() as u64;
306        len.ser_bin(s);
307        for (k, v) in self {
308            k.ser_bin(s);
309            v.ser_bin(s);
310        }
311    }
312}
313
314impl<K, V> DeBin for HashMap<K, V> where K: DeBin + Eq + Hash,
315V: DeBin {
316    fn de_bin(o:&mut usize, d:&[u8])->Result<Self, DeBinErr>{
317        let len:u64 = DeBin::de_bin(o,d)?;
318        let mut h = HashMap::new();
319        for _ in 0..len{
320            let k = DeBin::de_bin(o,d)?;
321            let v = DeBin::de_bin(o,d)?;
322            h.insert(k, v);
323        }
324        Ok(h)
325    }
326}
327
328
329impl<T> SerBin for Box<T> where T: SerBin {
330    fn ser_bin(&self, s: &mut Vec<u8>) {
331        (**self).ser_bin(s)
332    }
333}
334
335impl<T> DeBin for Box<T> where T: DeBin {
336    fn de_bin(o:&mut usize, d:&[u8])->Result<Box<T>, DeBinErr> {
337        Ok(Box::new(DeBin::de_bin(o,d)?))
338    }
339}
340
341#[cfg(any(target_os = "android", target_os = "linux", target_os="macos"))]
342impl SerBin for PathBuf {
343    fn ser_bin(&self, s: &mut Vec<u8>) {
344        self.as_os_str().ser_bin(s)
345    }
346}
347
348#[cfg(any(target_os = "android", target_os = "linux", target_os="macos"))]
349impl SerBin for Path {
350    fn ser_bin(&self, s: &mut Vec<u8>) {
351        self.as_os_str().ser_bin(s)
352    }
353}
354
355#[cfg(any(target_os = "android", target_os = "linux", target_os="macos"))]
356impl SerBin for OsString {
357    fn ser_bin(&self, s: &mut Vec<u8>) {
358        self.as_os_str().ser_bin(s)
359    }
360}
361
362#[cfg(any(target_os = "android", target_os = "linux", target_os="macos"))]
363impl SerBin for OsStr {
364    fn ser_bin(&self, s: &mut Vec<u8>) {
365        use std::os::unix::ffi::OsStrExt;
366
367        self.as_bytes().ser_bin(s)
368    }
369} 
370
371impl SerBin for char {
372    fn ser_bin(&self, s: &mut Vec<u8>) {
373        let mut bytes = [0; 4];
374        self.encode_utf8(&mut bytes).as_bytes().ser_bin(s);
375    }
376}
377
378#[cfg(unix)]
379impl DeBin for PathBuf {
380    fn de_bin(o: &mut usize, d: &[u8]) -> Result<Self, DeBinErr> {
381        Ok(PathBuf::from(OsString::de_bin(o, d)?))
382    }
383}
384
385#[cfg(unix)]
386impl DeBin for OsString {
387    fn de_bin(o: &mut usize, d: &[u8]) -> Result<Self, DeBinErr> {
388        use std::os::unix::ffi::OsStringExt;
389
390        Ok(OsString::from_vec(Vec::de_bin(o, d)?))
391    }
392}
393
394impl DeBin for char {
395    fn de_bin(o: &mut usize, d: &[u8]) -> Result<Self, DeBinErr> {
396        let mut bytes = [0; 4];
397        bytes[0] = u8::de_bin(o, d)?;
398        let width = utf8_char_width(bytes[0]);
399        for byte in &mut bytes[1..width] {
400            *byte = u8::de_bin(o, d)?;
401        }
402        Ok(str::from_utf8(&bytes[..width])
403            .unwrap()
404            .chars()
405            .next()
406            .unwrap())
407    }
408}
409
410// Given a first byte, determines how many bytes are in this UTF-8 character.
411#[inline]
412pub fn utf8_char_width(b: u8) -> usize {
413    static UTF8_CHAR_WIDTH: [u8; 256] = [
414        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
415        1, // 0x1F
416        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
417        1, // 0x3F
418        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
419        1, // 0x5F
420        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
421        1, // 0x7F
422        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
423        0, // 0x9F
424        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
425        0, // 0xBF
426        0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
427        2, // 0xDF
428        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xEF
429        4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xFF
430    ];
431
432    UTF8_CHAR_WIDTH[b as usize] as usize
433}