mbon/
parser.rs

1//! # Parse mbon data
2//!
3//! Use [Parser] to deserialize mbon data.
4
5use crate::{
6    data::{Mark, Type, Value},
7    error::{Error, Result},
8    object::ObjectParse,
9};
10use byteorder::{BigEndian, ReadBytesExt};
11use serde::de::DeserializeOwned;
12
13use std::io::{Read, Seek, SeekFrom};
14
15/// A struct that parses binary data from a bytearray
16///
17/// You can deserialize data using
18/// * [`next()`](Parser::next)
19/// * [`next_obj()`](Parser::next_obj)
20///
21/// Or you can deserialize data directly using
22/// * [`next_value()`](Parser::next_value)
23pub struct Parser<R>(R);
24
25impl<'a, T> From<&'a T> for Parser<&'a [u8]>
26where
27    T: AsRef<[u8]>,
28{
29    fn from(slice: &'a T) -> Self {
30        Self(slice.as_ref())
31    }
32}
33
34impl<R> From<R> for Parser<R>
35where
36    R: Read,
37{
38    fn from(reader: R) -> Self {
39        Self(reader)
40    }
41}
42
43impl<R> AsRef<R> for Parser<R> {
44    fn as_ref(&self) -> &R {
45        &self.0
46    }
47}
48
49impl<R> AsMut<R> for Parser<R> {
50    fn as_mut(&mut self) -> &mut R {
51        &mut self.0
52    }
53}
54
55impl<R> Parser<R>
56where
57    R: Read,
58{
59    /// Turn the parser into the underlying reader
60    #[inline]
61    pub fn reader(self) -> R {
62        self.0
63    }
64
65    /// Get the the underlying reader as a reference
66    #[inline]
67    pub fn get_reader(&self) -> &R {
68        &self.0
69    }
70
71    /// Get the the underlying reader as a mutable reference
72    #[inline]
73    pub fn get_reader_mut(&mut self) -> &mut R {
74        &mut self.0
75    }
76
77    /// Parse the next item in the parser.
78    ///
79    /// ### Example
80    ///
81    /// ```
82    /// use mbon::parser::Parser;
83    ///
84    /// let mut parser = Parser::from(b"i\x00\x00\x00\x42");
85    /// let i: u32 = parser.next().unwrap();
86    ///
87    /// assert_eq!(i, 0x42);
88    /// ```
89    #[inline]
90    pub fn next<T>(&mut self) -> Result<T>
91    where
92        T: DeserializeOwned,
93    {
94        self.next_value()?.parse()
95    }
96
97    /// Parse the next custom object in the parser.
98    ///
99    /// This allows you to be able to parse custom binary data. A common usecase
100    /// is to store a struct in a more compact form. You could also use object
101    /// values to store a different format altogether.
102    ///
103    /// Note: the next value in the parser must be an Object
104    ///
105    /// ### Example
106    ///
107    /// ```
108    /// use mbon::error::Error;
109    /// use mbon::parser::Parser;
110    /// use mbon::object::ObjectParse;
111    ///
112    /// struct Foo {
113    ///     a: i32,
114    ///     b: String,
115    ///     c: f32,
116    /// }
117    ///
118    /// impl ObjectParse for Foo {
119    ///     type Error = Error;
120    ///
121    ///     fn parse_object(data: &[u8]) -> Result<Self, Self::Error> {
122    ///         let mut parser = Parser::from(data);
123    ///         let a = parser.next()?;
124    ///         let b = parser.next()?;
125    ///         let c = parser.next()?;
126    ///         Ok(Self { a, b, c })
127    ///     }
128    /// }
129    ///
130    /// let mut parser =
131    /// Parser::from(
132    ///     b"o\x00\x00\x00\x14i\x00\x00\x00\x42s\x00\x00\x00\x05Hellof\x00\x00\x00\x00"
133    /// );
134    ///
135    /// let foo: Foo = parser.next_obj().unwrap();
136    /// assert_eq!(foo.a, 0x42);
137    /// assert_eq!(foo.b, "Hello");
138    /// assert_eq!(foo.c, 0.0);
139    /// ```
140    #[inline]
141    pub fn next_obj<T>(&mut self) -> Result<T>
142    where
143        T: ObjectParse,
144        <T as ObjectParse>::Error: std::error::Error + 'static,
145    {
146        self.next_value()?.parse_obj()
147    }
148
149    #[inline]
150    fn next_type(&mut self) -> Result<Type> {
151        Type::from_prefix(self.0.read_u8()?)
152    }
153
154    fn next_data_n(&mut self, n: usize) -> Result<Vec<u8>> {
155        let mut buf = vec![0; n];
156        self.0.read_exact(&mut buf)?;
157        Ok(buf)
158    }
159
160    #[inline]
161    fn next_data_long(&mut self) -> Result<i64> {
162        Ok(self.0.read_i64::<BigEndian>()?)
163    }
164
165    #[inline]
166    fn next_data_int(&mut self) -> Result<i32> {
167        Ok(self.0.read_i32::<BigEndian>()?)
168    }
169
170    #[inline]
171    fn next_data_short(&mut self) -> Result<i16> {
172        Ok(self.0.read_i16::<BigEndian>()?)
173    }
174
175    #[inline]
176    fn next_data_char(&mut self) -> Result<i8> {
177        Ok(self.0.read_i8()?)
178    }
179
180    #[inline]
181    fn next_data_float(&mut self) -> Result<f32> {
182        Ok(self.0.read_f32::<BigEndian>()?)
183    }
184
185    #[inline]
186    fn next_data_double(&mut self) -> Result<f64> {
187        Ok(self.0.read_f64::<BigEndian>()?)
188    }
189
190    #[inline]
191    fn next_data_bytes(&mut self, n: usize) -> Result<Vec<u8>> {
192        self.next_data_n(n)
193    }
194
195    #[inline]
196    fn next_data_str(&mut self, n: usize) -> Result<String> {
197        let buf = self.next_data_n(n)?;
198        Ok(String::from_utf8(buf)?)
199    }
200
201    fn next_data_enum(&mut self, m: &Mark) -> Result<(u32, Value)> {
202        let variant = self.next_data_int()? as u32;
203        let value = self.next_data_value(m)?;
204        Ok((variant, value))
205    }
206
207    fn next_data_array(&mut self, len: usize, t: &Mark) -> Result<Vec<Value>> {
208        let mut arr = Vec::with_capacity(len);
209
210        for _ in 0..len {
211            let v = self.next_data_value(t)?;
212            arr.push(v);
213        }
214
215        Ok(arr)
216    }
217
218    fn next_data_list(&mut self, size: usize) -> Result<Vec<Value>> {
219        let mut arr = Vec::new();
220
221        let mut read = 0;
222
223        while read < size {
224            let m = self.next_mark()?;
225            let v = self.next_data_value(&m)?;
226            arr.push(v);
227            read += m.size();
228        }
229
230        if read > size {
231            return Err(Error::data_error("List was larger than expected"));
232        }
233
234        Ok(arr)
235    }
236
237    fn next_data_dict(&mut self, len: usize, k: &Mark, v: &Mark) -> Result<Vec<(Value, Value)>> {
238        let mut arr = Vec::with_capacity(len);
239
240        for _ in 0..len {
241            let key = self.next_data_value(k)?;
242            let val = self.next_data_value(v)?;
243            arr.push((key, val));
244        }
245
246        Ok(arr)
247    }
248
249    fn next_data_map(&mut self, size: usize) -> Result<Vec<(Value, Value)>> {
250        let mut arr = Vec::new();
251        let mut read = 0;
252
253        while read < size {
254            let k = self.next_mark()?;
255            let key = self.next_data_value(&k)?;
256            let v = self.next_mark()?;
257            let val = self.next_data_value(&v)?;
258
259            arr.push((key, val));
260            read += k.size() + v.size();
261        }
262
263        if read > size {
264            return Err(Error::data_error("Map was larger than expected"));
265        }
266
267        Ok(arr)
268    }
269
270    pub(crate) fn next_data_value(&mut self, mark: &Mark) -> Result<Value> {
271        Ok(match mark {
272            Mark::Long => Value::Long(self.next_data_long()?),
273            Mark::Int => Value::Int(self.next_data_int()?),
274            Mark::Short => Value::Short(self.next_data_short()?),
275            Mark::Char => Value::Char(self.next_data_char()?),
276            Mark::Float => Value::Float(self.next_data_float()?),
277            Mark::Double => Value::Double(self.next_data_double()?),
278            Mark::Bytes(n) => Value::Bytes(self.next_data_bytes(*n)?),
279            Mark::Str(n) => Value::Str(self.next_data_str(*n)?.to_owned()),
280            Mark::Object(n) => Value::Object(self.next_data_bytes(*n)?.to_vec()),
281            Mark::Enum(m) => {
282                let (var, val) = self.next_data_enum(&m)?;
283                Value::Enum(var, Box::new(val))
284            }
285            Mark::Null => Value::Null,
286            Mark::Array(n, m) => Value::List(self.next_data_array(*n, &m)?),
287            Mark::List(n) => Value::List(self.next_data_list(*n)?),
288            Mark::Dict(n, k, v) => Value::Map(self.next_data_dict(*n, &k, &v)?),
289            Mark::Map(n) => Value::Map(self.next_data_map(*n)?),
290        })
291    }
292
293    fn next_mark(&mut self) -> Result<Mark> {
294        let t = self.next_type()?;
295        Ok(match t {
296            Type::Long => Mark::Long,
297            Type::Int => Mark::Int,
298            Type::Short => Mark::Short,
299            Type::Char => Mark::Char,
300            Type::Float => Mark::Float,
301            Type::Double => Mark::Double,
302            Type::Bytes => Mark::Bytes(self.next_data_int()? as usize),
303            Type::Str => Mark::Str(self.next_data_int()? as usize),
304            Type::Object => Mark::Object(self.next_data_int()? as usize),
305            Type::Enum => Mark::Enum(Box::new(self.next_mark()?)),
306            Type::Null => Mark::Null,
307            Type::Array => {
308                let mark = self.next_mark()?;
309                let len = self.next_data_int()? as usize;
310                Mark::Array(len, Box::new(mark))
311            }
312            Type::List => Mark::List(self.next_data_int()? as usize),
313            Type::Dict => {
314                let k = self.next_mark()?;
315                let v = self.next_mark()?;
316                let len = self.next_data_int()? as usize;
317                Mark::Dict(len, Box::new(k), Box::new(v))
318            }
319            Type::Map => Mark::Map(self.next_data_int()? as usize),
320        })
321    }
322
323    /// Skip the next value in the parser.
324    ///
325    /// This will ignore the next value without parsing more than what's
326    /// necessary.
327    ///
328    /// If the reader supports seeking, then it is preffered to use
329    /// [`seek_next()`](Parser::seek_next) instead.
330    ///
331    /// ### Example
332    ///
333    /// ```
334    /// use mbon::parser::Parser;
335    ///
336    /// let mut parser = Parser::from(
337    ///     b"s\x00\x00\x00\x1eI don't care about this stringi\x00\x00\x00\x42"
338    /// );
339    ///
340    /// parser.skip_next().unwrap();
341    ///
342    /// let v: i32 = parser.next().unwrap();
343    /// assert_eq!(v, 0x42);
344    /// ```
345    pub fn skip_next(&mut self) -> Result<()> {
346        let mark = self.next_mark()?;
347        let size = mark.data_size();
348
349        self.next_data_n(size)?;
350
351        Ok(())
352    }
353
354    /// Parse the next value in the parser.
355    ///
356    /// This will try to read whatever value is next and return it.
357    ///
358    /// ### Example
359    ///
360    /// ```
361    /// use mbon::parser::Parser;
362    /// use mbon::data::Value;
363    ///
364    /// let mut parser = Parser::from(b"i\x00\x00\x00\x42");
365    ///
366    /// assert_eq!(parser.next_value().unwrap(), Value::Int(0x42));
367    /// ```
368    #[inline]
369    pub fn next_value(&mut self) -> Result<Value> {
370        let mark = self.next_mark()?;
371        self.next_data_value(&mark)
372    }
373}
374
375impl<R> Parser<R>
376where
377    R: Read + Seek,
378{
379    /// Seek to the next value in the parser.
380    ///
381    /// This will efficiently skip the next value without reading more than
382    /// what's necessary.
383    ///
384    /// ### Example
385    ///
386    /// ```
387    /// use mbon::parser::Parser;
388    /// use std::io::Cursor;
389    ///
390    /// let reader = Cursor::new(
391    ///     b"s\x00\x00\x00\x23This is a string I don't care abouti\x00\x00\x00\x20"
392    /// );
393    ///
394    /// let mut parser = Parser::from(reader);
395    ///
396    /// parser.seek_next().unwrap();
397    /// let val: u32 = parser.next().unwrap();
398    ///
399    /// assert_eq!(val, 32);
400    /// ```
401    pub fn seek_next(&mut self) -> Result<()> {
402        let mark = self.next_mark()?;
403        let size = mark.data_size();
404
405        self.0.seek(SeekFrom::Current(size as i64))?;
406
407        Ok(())
408    }
409}
410
411#[cfg(test)]
412mod test {
413    use super::*;
414
415    #[test]
416    fn test_long() {
417        let mut parser = Parser::from(b"l\x00\x30\x00\x00\x20\x10\x00\x05");
418        let val = parser.next_value().unwrap();
419        assert_eq!(val, Value::Long(0x0030000020100005));
420        assert_eq!(parser.0.is_empty(), true);
421    }
422
423    #[test]
424    fn test_int() {
425        let mut parser = Parser::from(b"i\x03\x00\x00\x00");
426        let val = parser.next_value().unwrap();
427        assert_eq!(val, Value::Int(0x03000000));
428        assert_eq!(parser.0.is_empty(), true);
429    }
430
431    #[test]
432    fn test_short() {
433        let mut parser = Parser::from(b"h\x03\x00");
434        let val = parser.next_value().unwrap();
435        assert_eq!(val, Value::Short(0x0300));
436        assert_eq!(parser.0.is_empty(), true);
437    }
438
439    #[test]
440    fn test_char() {
441        let mut parser = Parser::from(b"c\x03");
442        let val = parser.next_value().unwrap();
443        assert_eq!(val, Value::Char(0x03));
444        assert_eq!(parser.0.is_empty(), true);
445    }
446
447    #[test]
448    fn test_float() {
449        let mut parser = Parser::from(b"f\x00\x00\x00\x00");
450        let val = parser.next_value().unwrap();
451        assert_eq!(val, Value::Float(0.0));
452        assert_eq!(parser.0.is_empty(), true);
453    }
454
455    #[test]
456    fn test_double() {
457        let mut parser = Parser::from(b"d\x00\x00\x00\x00\x00\x00\x00\x00");
458        let val = parser.next_value().unwrap();
459        assert_eq!(val, Value::Double(0.0));
460        assert_eq!(parser.0.is_empty(), true);
461    }
462
463    #[test]
464    fn test_bytes() {
465        let mut parser = Parser::from(b"b\x00\x00\x00\x0bHello World");
466        let val = parser.next_value().unwrap();
467        assert_eq!(val, Value::Bytes(b"Hello World".to_vec()));
468        assert_eq!(parser.0.is_empty(), true);
469    }
470
471    #[test]
472    fn test_str() {
473        let mut parser = Parser::from(b"s\x00\x00\x00\x0bHello World");
474        let val = parser.next_value().unwrap();
475        assert_eq!(val, Value::Str("Hello World".to_owned()));
476        assert_eq!(parser.0.is_empty(), true);
477    }
478
479    #[test]
480    fn test_object() {
481        let mut parser = Parser::from(b"o\x00\x00\x00\x0bHello World");
482        let val = parser.next_value().unwrap();
483        assert_eq!(val, Value::Object(b"Hello World".to_vec()));
484        assert_eq!(parser.0.is_empty(), true);
485    }
486
487    #[test]
488    fn test_enum() {
489        let mut parser = Parser::from(b"ei\x00\x00\x00\x01\x00\x00\x00\xfe");
490        let val = parser.next_value().unwrap();
491        assert_eq!(val, Value::Enum(1, Box::new(Value::Int(0xfe))));
492        assert_eq!(parser.0.is_empty(), true);
493    }
494
495    #[test]
496    fn test_null() {
497        let mut parser = Parser::from(b"n");
498        let val = parser.next_value().unwrap();
499        assert_eq!(val, Value::Null);
500        assert_eq!(parser.0.is_empty(), true);
501    }
502
503    #[test]
504    fn test_array() {
505        let mut parser = Parser::from(b"ac\x00\x00\x00\x04\x01\x02\x03\x04");
506        let val = parser.next_value().unwrap();
507        if let Value::List(val) = val {
508            assert_eq!(val.len(), 4);
509            assert_eq!(val.get(0).unwrap().to_owned(), Value::Char(1));
510            assert_eq!(val.get(1).unwrap().to_owned(), Value::Char(2));
511            assert_eq!(val.get(2).unwrap().to_owned(), Value::Char(3));
512            assert_eq!(val.get(3).unwrap().to_owned(), Value::Char(4));
513        } else {
514            panic!("value is not a list");
515        }
516        assert_eq!(parser.0.is_empty(), true);
517    }
518
519    #[test]
520    fn test_2d_array() {
521        let mut parser = Parser::from(
522            b"aac\x00\x00\x00\x05\x00\x00\x00\x03\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
523        );
524        let val = parser.next_value().unwrap();
525        if let Value::List(val) = val {
526            let mut i = 1;
527            for v in val {
528                if let Value::List(v) = v {
529                    for item in v {
530                        assert_eq!(item, Value::Char(i));
531                        i += 1;
532                    }
533                } else {
534                    panic!("nested value is not a list");
535                }
536            }
537        } else {
538            panic!("value is not a list")
539        }
540    }
541
542    #[test]
543    fn test_list() {
544        let mut parser = Parser::from(b"A\x00\x00\x00\x08c\x01c\x02c\x03c\x04");
545        let val = parser.next_value().unwrap();
546        if let Value::List(val) = val {
547            assert_eq!(val.len(), 4);
548            assert_eq!(val.get(0).unwrap().to_owned(), Value::Char(1));
549            assert_eq!(val.get(1).unwrap().to_owned(), Value::Char(2));
550            assert_eq!(val.get(2).unwrap().to_owned(), Value::Char(3));
551            assert_eq!(val.get(3).unwrap().to_owned(), Value::Char(4));
552        } else {
553            panic!("value is not a list");
554        }
555        assert_eq!(parser.0.is_empty(), true);
556    }
557
558    #[test]
559    fn test_map() {
560        let mut parser =
561            Parser::from(b"M\x00\x00\x00\x10s\x00\x00\x00\x01ac\x01s\x00\x00\x00\x01bc\x02");
562        let val = parser.next_value().unwrap();
563        if let Value::Map(val) = val {
564            assert_eq!(val.len(), 2);
565            assert_eq!(
566                val.get(0).unwrap().to_owned(),
567                (Value::Str("a".to_owned()), Value::Char(1))
568            );
569            assert_eq!(
570                val.get(1).unwrap().to_owned(),
571                (Value::Str("b".to_owned()), Value::Char(2))
572            );
573        } else {
574            panic!("value is not a map");
575        }
576        assert_eq!(parser.0.is_empty(), true);
577    }
578
579    #[test]
580    fn test_eof() {
581        let mut parser = Parser::from(b"i\x00\x0a");
582
583        let err = parser.next_value().expect_err("UnexpectedEof Error");
584
585        if let Error::IO(e) = err {
586            if e.kind() != std::io::ErrorKind::UnexpectedEof {
587                panic!("Expected UnexpectedEof Error");
588            }
589        } else {
590            panic!("Expected UnexpectedEof Error");
591        }
592    }
593
594    #[test]
595    fn test_list_too_big() {
596        let mut parser = Parser::from(b"A\x00\x00\x00\x04c\x01i\x00\x00\x00\x00");
597
598        let err = parser.next_value().expect_err("DataError");
599        if let Error::DataError(_) = err {
600        } else {
601            panic!("Expected a DataError");
602        }
603    }
604
605    #[test]
606    fn test_map_too_big() {
607        let mut parser = Parser::from(b"M\x00\x00\x00\x04c\x01i\x00\x00\x00\x00");
608
609        let err = parser.next_value().expect_err("DataError");
610        if let Error::DataError(_) = err {
611        } else {
612            panic!("Expected a DataError");
613        }
614    }
615}