1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
mod error;
pub use error::*;
mod marker;
pub use marker::*;
mod container;
pub use container::*;
mod values;
pub use crate::values::*;
pub const MIME_TYPE: &str = "application/ubjson";
pub const FILE_EXT: &str = "ubj";
pub trait Parsable<'a>: Sized {
fn parse(i: &'a [u8]) -> nom::IResult<&'a [u8], Self, UbjsonError>;
}
#[inline(always)]
pub fn parse_one<'a>(i: &'a [u8]) -> nom::IResult<&'a [u8], Container, UbjsonError> {
Marker::parse(i).and_then(|(i, marker)| marker.parse_to_container(i))
}
#[inline(always)]
fn parse_length(i: &[u8]) -> nom::IResult<&[u8], usize, UbjsonError> {
use std::convert::TryInto as _;
let (i, marker) = Marker::parse(i)?;
let (i, container) = marker.parse_to_container(i)?;
let length = container.try_into().map_err(nom::Err::Failure)?;
Ok((i, length))
}
#[cfg(test)]
mod test {
use crate::parse_one;
const COMPLEX_COUCHDB: &[u8] = include_bytes!("../test/samples/complex/CouchDB4k.ubj");
const COMPLEX_MEDIA: &[u8] = include_bytes!("../test/samples/complex/MediaContent.ubj");
const COMPLEX_TWITTER: &[u8] = include_bytes!("../test/samples/complex/TwitterTimeline.ubj");
#[test]
fn test_complex_couchdb() {
let (_, _container) = parse_one(COMPLEX_COUCHDB).unwrap();
}
#[test]
fn test_complex_media() {
let (_, _container) = parse_one(COMPLEX_MEDIA).unwrap();
}
#[test]
fn test_complex_twitter() {
let (_, _container) = parse_one(COMPLEX_TWITTER).unwrap();
}
}