makepad_micro_serde/
serde_bin.rs

1use std::{
2    collections::HashMap,
3    hash::Hash,
4    str,
5};
6use makepad_live_id::LiveId;
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 SerBin for LiveId {
107    fn ser_bin(&self, s: &mut Vec<u8>) {
108        self.0.ser_bin(s);
109    }
110}
111
112impl DeBin for LiveId {
113    fn de_bin(o:&mut usize, d:&[u8]) -> Result<LiveId, DeBinErr> {
114        Ok(LiveId(u64::de_bin(o, d)?))
115    }
116}
117
118impl DeBin for u8 {
119    fn de_bin(o:&mut usize, d:&[u8]) -> Result<u8,DeBinErr> {
120        if *o + 1 > d.len(){
121            return Err(DeBinErr{o:*o, l:1, s:d.len(), msg:"u8".to_string()})
122        } 
123        let m = d[*o];
124        *o += 1;
125        Ok(m)
126    }
127}
128
129impl SerBin for u8 {
130    fn ser_bin(&self, s: &mut Vec<u8>) {
131        s.push(*self);
132    }
133}
134
135impl DeBin for i8 {
136    fn de_bin(o:&mut usize, d:&[u8]) -> Result<i8,DeBinErr> {
137        if *o + 1 > d.len(){
138            return Err(DeBinErr{o:*o, l:1, s:d.len(), msg:"u8".to_string()})
139        } 
140        let m = d[*o];
141        *o += 1;
142        Ok(m as i8)
143    }
144}
145
146impl SerBin for i8 {
147    fn ser_bin(&self, s: &mut Vec<u8>) {
148        s.push(*self as u8);
149    }
150}
151
152impl SerBin for bool {
153    fn ser_bin(&self, s: &mut Vec<u8>) {
154        s.push(if *self {1} else {0});
155    }
156}
157
158impl DeBin for bool {
159    fn de_bin(o:&mut usize, d:&[u8]) -> Result<bool, DeBinErr> {
160        if *o + 1 > d.len(){
161            return Err(DeBinErr{o:*o, l:1, s:d.len(), msg:"bool".to_string()})
162        } 
163        let m = d[*o];
164        *o += 1;
165        if m == 0{Ok(false)} else {Ok(true)}
166    }
167}
168
169impl SerBin for String {
170    fn ser_bin(&self, s: &mut Vec<u8>) {
171        let len = self.len();
172        len.ser_bin(s);
173        s.extend_from_slice(self.as_bytes());
174    }
175}
176
177impl DeBin for String {
178    fn de_bin(o:&mut usize, d:&[u8])->Result<String, DeBinErr> {
179        let len:u64 = DeBin::de_bin(o,d)?;
180        if *o + (len as usize) > d.len(){
181            return Err(DeBinErr{o:*o, l:1, s:d.len(), msg:"String".to_string()})
182        } 
183        let r = std::str::from_utf8(&d[*o..(*o+(len as usize))]).unwrap().to_string();
184        *o += len as usize;
185        Ok(r)
186    }
187}
188
189impl<T> SerBin for Vec<T> where T: SerBin {
190    fn ser_bin(&self, s: &mut Vec<u8>) {
191        let len = self.len() as u64;
192        len.ser_bin(s);
193        for item in self {
194            item.ser_bin(s);
195        }
196    }
197}
198
199impl<T> DeBin for Vec<T> where T:DeBin{
200    fn de_bin(o:&mut usize, d:&[u8])->Result<Vec<T>, DeBinErr> {
201        let len:u64 = DeBin::de_bin(o,d)?;
202        let mut out = Vec::new();
203        for _ in 0..len{
204            out.push(DeBin::de_bin(o,d)?)
205        }
206        Ok(out)
207    }
208}
209
210impl<T> SerBin for Option<T> where T: SerBin {
211    fn ser_bin(&self, s: &mut Vec<u8>) {
212        match self {
213            None => s.push(0),
214            Some(v) => {
215                s.push(1);
216                v.ser_bin(s);
217            }
218        }
219    }
220}
221
222impl<T> DeBin for Option<T> where T:DeBin{
223    fn de_bin(o:&mut usize, d:&[u8])->Result<Option<T>, DeBinErr> {
224        if *o + 1 > d.len(){
225            return Err(DeBinErr{o:*o, l:1, s:d.len(), msg:"Option<T>".to_string()})
226        } 
227        let m = d[*o];
228        *o += 1;
229        Ok(match m {
230            0 => None,
231            1 => Some(DeBin::de_bin(o,d)?),
232            _ => return Err(DeBinErr{o:*o, l:0, s:d.len(), msg:"Option<T>".to_string()}),
233        })
234    }
235}
236
237impl<T, E> SerBin for Result<T, E> where T: SerBin, E: SerBin {
238    fn ser_bin(&self, s: &mut Vec<u8>) {
239        match self {
240            Ok(v) => {
241                s.push(0);
242                v.ser_bin(s);
243            }
244            Err(e) => {
245                s.push(1);
246                e.ser_bin(s);
247            }
248        }
249    }
250}
251
252impl<T, E> DeBin for Result<T, E> where T: DeBin, E: DeBin {
253    fn de_bin(o: &mut usize, d: &[u8]) -> Result<Self, DeBinErr> {
254        if *o + 1 > d.len() {
255            return Err(DeBinErr{o:*o, l:1, s:d.len(), msg:"Result<T, E>".to_string()});
256        }
257        let m = d[*o];
258        *o += 1;
259        Ok(match m {
260            0 => Ok(T::de_bin(o, d)?),
261            1 => Err(E::de_bin(o, d)?),
262            _ => return Err(DeBinErr{o:*o, l:0, s:d.len(), msg:"Result<T, E>".to_string()}),
263        })
264    }
265}
266
267impl<T> SerBin for [T] where T: SerBin {
268    fn ser_bin(&self, s: &mut Vec<u8>) {
269        for item in self {
270            item.ser_bin(s);
271        }
272    }
273}
274
275
276unsafe fn de_bin_array_impl_inner<T>(top: *mut T, count: usize, o:&mut usize, d:&[u8]) -> Result<(), DeBinErr> where T:DeBin{
277    for c in 0..count {
278        top.add(c).write(DeBin::de_bin(o, d) ?);
279    }
280    Ok(())
281}
282
283impl<T, const N: usize> DeBin for [T; N] where T: DeBin {
284    fn de_bin(o:&mut usize, d:&[u8]) -> Result<Self,
285    DeBinErr> {
286        unsafe{
287            let mut to = std::mem::MaybeUninit::<[T; N]>::uninit();
288            let top: *mut T = &mut to as *mut _ as *mut T;
289            de_bin_array_impl_inner(top, N, o, d)?;
290            Ok(to.assume_init())
291        }
292    }
293}
294
295impl<A,B> SerBin for (A,B) where A: SerBin, B:SerBin {
296    fn ser_bin(&self, s: &mut Vec<u8>) {
297        self.0.ser_bin(s);
298        self.1.ser_bin(s);
299    }
300}
301
302impl<A,B> DeBin for (A,B) where A:DeBin, B:DeBin{
303    fn de_bin(o:&mut usize, d:&[u8])->Result<(A,B), DeBinErr> {Ok((DeBin::de_bin(o,d)?,DeBin::de_bin(o,d)?))}
304}
305
306impl<A,B,C> SerBin for (A,B,C) where A: SerBin, B:SerBin, C:SerBin {
307    fn ser_bin(&self, s: &mut Vec<u8>) {
308        self.0.ser_bin(s);
309        self.1.ser_bin(s);
310        self.2.ser_bin(s);
311    } 
312}
313
314impl<A,B,C> DeBin for (A,B,C) where A:DeBin, B:DeBin, C:DeBin{
315    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)?))}
316}
317
318impl<A,B,C,D> SerBin for (A,B,C,D) where A: SerBin, B:SerBin, C:SerBin, D:SerBin {
319    fn ser_bin(&self, s: &mut Vec<u8>) {
320        self.0.ser_bin(s);
321        self.1.ser_bin(s);
322        self.2.ser_bin(s);
323        self.3.ser_bin(s);
324    }
325}
326
327impl<A,B,C,D> DeBin for (A,B,C,D) where A:DeBin, B:DeBin, C:DeBin, D:DeBin{
328    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)?))}
329}
330
331impl<A,B,C,D,E> SerBin for (A,B,C,D,E) where A: SerBin, B:SerBin, C:SerBin, D:SerBin, E:SerBin {
332    fn ser_bin(&self, s: &mut Vec<u8>) {
333        self.0.ser_bin(s);
334        self.1.ser_bin(s);
335        self.2.ser_bin(s);
336        self.3.ser_bin(s);
337        self.4.ser_bin(s);
338    }
339}
340
341impl<A,B,C,D,E> DeBin for (A,B,C,D,E) where A:DeBin, B:DeBin, C:DeBin, D:DeBin, E:DeBin{
342    fn de_bin(o:&mut usize, d:&[u8])->Result<(A,B,C,D,E), DeBinErr> {Ok((DeBin::de_bin(o,d)?,DeBin::de_bin(o,d)?,DeBin::de_bin(o,d)?,DeBin::de_bin(o,d)?,DeBin::de_bin(o,d)?))}
343}
344
345impl<K, V> SerBin for HashMap<K, V> where K: SerBin,
346V: SerBin {
347    fn ser_bin(&self, s: &mut Vec<u8>) {
348        let len = self.len() as u64;
349        len.ser_bin(s);
350        for (k, v) in self {
351            k.ser_bin(s);
352            v.ser_bin(s);
353        }
354    }
355}
356
357impl<K, V> DeBin for HashMap<K, V> where K: DeBin + Eq + Hash,
358V: DeBin {
359    fn de_bin(o:&mut usize, d:&[u8])->Result<Self, DeBinErr>{
360        let len:u64 = DeBin::de_bin(o,d)?;
361        let mut h = HashMap::new();
362        for _ in 0..len{
363            let k = DeBin::de_bin(o,d)?;
364            let v = DeBin::de_bin(o,d)?;
365            h.insert(k, v);
366        }
367        Ok(h)
368    }
369}
370
371
372impl<T> SerBin for Box<T> where T: SerBin {
373    fn ser_bin(&self, s: &mut Vec<u8>) {
374        (**self).ser_bin(s)
375    }
376}
377
378impl<T> DeBin for Box<T> where T: DeBin {
379    fn de_bin(o:&mut usize, d:&[u8])->Result<Box<T>, DeBinErr> {
380        Ok(Box::new(DeBin::de_bin(o,d)?))
381    }
382}
383
384#[cfg(any(target_os = "android", target_os = "linux", target_os="macos"))]
385impl SerBin for PathBuf {
386    fn ser_bin(&self, s: &mut Vec<u8>) {
387        self.as_os_str().ser_bin(s)
388    }
389}
390
391#[cfg(any(target_os = "android", target_os = "linux", target_os="macos"))]
392impl SerBin for Path {
393    fn ser_bin(&self, s: &mut Vec<u8>) {
394        self.as_os_str().ser_bin(s)
395    }
396}
397
398#[cfg(any(target_os = "android", target_os = "linux", target_os="macos"))]
399impl SerBin for OsString {
400    fn ser_bin(&self, s: &mut Vec<u8>) {
401        self.as_os_str().ser_bin(s)
402    }
403}
404
405#[cfg(any(target_os = "android", target_os = "linux", target_os="macos"))]
406impl SerBin for OsStr {
407    fn ser_bin(&self, s: &mut Vec<u8>) {
408        use std::os::unix::ffi::OsStrExt;
409
410        self.as_bytes().ser_bin(s)
411    }
412} 
413
414impl SerBin for char {
415    fn ser_bin(&self, s: &mut Vec<u8>) {
416        let mut bytes = [0; 4];
417        self.encode_utf8(&mut bytes).as_bytes().ser_bin(s);
418    }
419}
420/*
421#[cfg(unix)]
422impl DeBin for PathBuf {
423    fn de_bin(o: &mut usize, d: &[u8]) -> Result<Self, DeBinErr> {
424        Ok(PathBuf::from(OsString::de_bin(o, d)?))
425    }
426}
427
428#[cfg(unix)]
429impl DeBin for OsString {
430    fn de_bin(o: &mut usize, d: &[u8]) -> Result<Self, DeBinErr> {
431        use std::os::unix::ffi::OsStringExt;
432
433        Ok(OsString::from_vec(Vec::de_bin(o, d)?))
434    }
435}*/
436
437impl DeBin for char {
438    fn de_bin(o: &mut usize, d: &[u8]) -> Result<Self, DeBinErr> {
439        let mut bytes = [0; 4];
440        bytes[0] = u8::de_bin(o, d)?;
441        let width = utf8_char_width(bytes[0]);
442        for byte in &mut bytes[1..width] {
443            *byte = u8::de_bin(o, d)?;
444        }
445        Ok(str::from_utf8(&bytes[..width])
446            .unwrap()
447            .chars()
448            .next()
449            .unwrap())
450    }
451}
452
453// Given a first byte, determines how many bytes are in this UTF-8 character.
454#[inline]
455pub fn utf8_char_width(b: u8) -> usize {
456    static UTF8_CHAR_WIDTH: [u8; 256] = [
457        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,
458        1, // 0x1F
459        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,
460        1, // 0x3F
461        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,
462        1, // 0x5F
463        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,
464        1, // 0x7F
465        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,
466        0, // 0x9F
467        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,
468        0, // 0xBF
469        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,
470        2, // 0xDF
471        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xEF
472        4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0xFF
473    ];
474
475    UTF8_CHAR_WIDTH[b as usize] as usize
476}