Skip to main content

dbin/
lib.rs

1mod context;
2mod data;
3mod expr;
4mod parser;
5pub mod prelude;
6mod pvec;
7mod render;
8pub mod samples;
9
10pub use context::Context;
11pub use context::Scope;
12pub use data::Data;
13pub use expr::Expr;
14pub use parser::ParseError;
15pub use parser::Pattern;
16pub use pvec::PatternVec;
17pub use render::render;
18pub use render::Render;
19pub use render::Renderable;
20
21fn err<T, S: Into<String>>(s: S) -> Result<T, ParseError> {
22    Err(ParseError::Other(s.into()))
23}
24
25pub enum Endian {
26    Little,
27    Big,
28}
29
30#[cfg(test)]
31mod tests {
32    use super::*;
33
34    #[test]
35    fn sample() {
36        let bytes = render((1234u64, 50000u16));
37        let parser = {
38            use prelude::*;
39
40            all_of((magic_u64(1234), U8, U8))
41        };
42
43        let data = parser.parse(&bytes).unwrap();
44
45        assert_eq!(
46            data,
47            Data::fseq(vec![Data::Int(1234), Data::Int(80), Data::Int(195),])
48        );
49        assert_eq!(50000, (195 << 8) + 80);
50    }
51
52    #[test]
53    fn alternatives() {
54        let bytes = render((1234u64, 50000u16));
55        let parser = {
56            use prelude::*;
57            any_of((
58                all_of((all_of(()).mapval("big-endian"), be_magic_u64(1234), BE_U16)),
59                all_of((
60                    all_of(()).mapval("little-endian"),
61                    le_magic_u64(1234),
62                    U8,
63                    U8,
64                )),
65            ))
66        };
67
68        let data = parser.parse(&bytes).unwrap();
69
70        assert_eq!(
71            data,
72            Data::fseq(vec![
73                "little-endian".into(),
74                Data::Int(1234),
75                Data::Int(80),
76                Data::Int(195),
77            ])
78        );
79        assert_eq!(50000, (195 << 8) + 80);
80    }
81
82    #[test]
83    fn list() {
84        let bytes = render((
85            1234u32, // magic
86            3u32,    // length - 1
87            (
88                777u64, 888u64, 999u64, 444u64, // data to be parsed
89                555u64, 666u64, // just some extra data
90            ),
91        ));
92
93        enum Key {
94            LENGTH,
95        }
96
97        let parser = {
98            use prelude::*;
99            all_of((
100                le_magic_u32(1234),
101                // after magic, the header specifies length of
102                // upcoming array - 1
103                // Store the computed length to 'Key::LENGTH'
104                U32.add(1).store(Key::LENGTH as i64),
105                // finally, specify an array of u64,
106                // whose length is determined by the Key::LENGTH
107                // value stored above
108                array_of(LE_U64, getvar(Key::LENGTH as i64)),
109            ))
110        };
111
112        let data = parser.parse(&bytes).unwrap();
113
114        assert_eq!(
115            data,
116            Data::fseq(vec![
117                Data::Int(1234), // magic,
118                Data::Int(4),    // length
119                // the actual array
120                Data::fseq(vec![
121                    Data::Int(777),
122                    Data::Int(888),
123                    Data::Int(999),
124                    Data::Int(444),
125                ]),
126            ])
127        );
128
129        // try again, but with lenght a little longer
130        let bytes = render((
131            1234u32, // magic
132            4u32,    // length - 1
133            (
134                777u64, 888u64, 999u64, 444u64, // data to be parsed
135                555u64, 666u64, // just some extra data
136            ),
137        ));
138
139        let data = parser.parse(&bytes).unwrap();
140
141        assert_eq!(
142            data,
143            Data::fseq(vec![
144                Data::Int(1234), // magic,
145                Data::Int(5),    // length
146                // the actual array
147                Data::fseq(vec![
148                    Data::Int(777),
149                    Data::Int(888),
150                    Data::Int(999),
151                    Data::Int(444),
152                    Data::Int(555),
153                ]),
154            ])
155        );
156    }
157}