1#[cxx::bridge(namespace = "simdjson_sys::dom")]
2pub mod dom_ffi {
3 struct TapeView<'a> {
4 tape: &'a [u64],
5 string_buf: &'a [u8],
6 }
7
8 unsafe extern "C++" {
9 include!("simdjson.h");
10 include!("simdjson_dom_bridge.h");
11
12 #[namespace = "simdjson::dom"]
13 type parser;
14
15 fn parser_new(max_capacity: usize) -> UniquePtr<parser>;
16 #[allow(clippy::missing_safety_doc)]
24 unsafe fn parser_parse(
25 parser: Pin<&mut parser>,
26 json: &[u8],
27 realloc_if_needed: bool,
28 ) -> i32;
29 #[allow(clippy::missing_safety_doc)]
35 unsafe fn parser_get_tape_view(parser: &parser) -> TapeView<'_>;
36 }
37}
38
39pub const SIMDJSON_PADDING: usize = 64;
40pub const SIMDJSON_MAXSIZE_BYTES: usize = 0xFFFFFFFF;
41pub const DEFAULT_BATCH_SIZE: usize = 1000000;
42
43#[cfg(test)]
44mod tests {
45 use super::*;
46
47 #[test]
48 fn parser_parses_string_and_exposes_tape_view() {
49 let mut parser = dom_ffi::parser_new(SIMDJSON_MAXSIZE_BYTES);
50 let json = String::from(r#"{"answer":42,"message":"ok"}"#);
51
52 assert_eq!(
54 unsafe { dom_ffi::parser_parse(parser.pin_mut(), json.as_bytes(), true) },
55 0
56 );
57
58 let view = unsafe { dom_ffi::parser_get_tape_view(parser.as_ref().unwrap()) };
60 assert!(!view.tape.is_empty());
61 assert_eq!(view.tape[0] >> 56, u64::from(b'r'));
62 assert!(!view.string_buf.is_empty());
63 }
64 #[test]
65 fn string_view_contains_only_initialized_prefix() {
66 let mut parser = dom_ffi::parser_new(SIMDJSON_MAXSIZE_BYTES);
67 for (json, expected) in [
68 (r#"["longer string", "x"]"#, 24),
69 ("[2449958197289549824]", 0),
71 (r#""x""#, 6),
72 ("null", 0),
73 ] {
74 assert_eq!(
76 unsafe { dom_ffi::parser_parse(parser.pin_mut(), json.as_bytes(), true) },
77 0
78 );
79 let view = unsafe { dom_ffi::parser_get_tape_view(parser.as_ref().unwrap()) };
81 assert_eq!(view.string_buf.len(), expected, "{json}");
82 }
83 }
84}