A JSON parser with span tracking and optional comment support.
For most use cases, all you need is the actual JSON data:
use flexon::parse;
let src = r#"{"blah": "was it really necessary?"}"#;
let val: &Span<Value> = parse(src).unwrap()["blah"];
println!("{val:#?} at {}..={}", val.start(), val.end());But wait, what about comments? For that you need to enable comment feature
use flexon::{Parser, source::Slice};
let src = r#"
{
// A single-line comment
"nested": {
"one": "hello world"
}
/*
* A multi-line comment
*/
"mixed": [true, null, 1]
}
"#;
let parser = Parser::new(
Slice::from(src),
false, // Require commas
false, // Allow trailing commas (has no effect when commas are optional)
);
let (_, comments) = parser.parse().unwrap();
let (cmnt, is_multi_line) = comments[0].data();
println!("{cmnt:?}");
assert!(!is_multi_line);
let (cmnt, is_multi_line) = comments[1].data();
println!("{cmnt:?}");
assert!(is_multi_line);
// Index 11 falls within the single-line comment's range.
assert!(comments.find_comment(11).is_some());
// With the `line-count` feature enabled, you can find a comment by its line index.
// In that case, the parser returns `Metadata` instead of `Vec<..>`.
assert!(comments.find_comment_by_line(7).is_some());comment: Enable comment parsing. The performance overhead is significant.
line-count: Include line information and allow searching comments by line index. Performance overhead is somewhat minimal.
prealloc (default): Pre-allocate memory for array/object when parsing based on the length of previously parsed array/object. Can improve performance at the cost of potentially increased/reduced memory usage. Works particularly well when the JSON has a relatively uniform and repetitive structure. This can also become an overhead if you use a custom allocator like snmalloc, mimalloc or jemalloc instead.
span: Include span information on the parsed JSON data. Performance overhead is minimal and memory usage will increase roughly by 33%.
serde-json: Implements Into<serde_json::Value> for flexon::Value.
This was created solely for parsing JSON with span support and comments, so it has overhead than other crates like serde-json, jzon or simd-json. The performance is somewhat close to serde-json or sometimes even better, depending on the case. For reference, here are their benchmark on x86_64:
serde-json:
canada 14.29 ms 140.14 MiB/s
twitter 2.40 ms 250.67 MiB/s
citm_catalog 4.21 ms 390.89 MiB/s
flexon:
canada 10.67 ms 201.05 MiB/s
twitter 2.42 ms 247.94 MiB/s
citm_catalog 3.97 ms 414.85 MiB/s
flexon (without span):
canada 9.90 ms 216.67 MiB/s
twitter 2.35 ms 256.18 MiB/s
citm_catalog 3.92 ms 420.09 MiB/s
Even though it can parse standard, strict JSON, you shouldn’t use it for that unless you need to parse JSON with comments or span support. Don’t torture yourself and just use one of the faster crates mentioned earlier. Fyi, this crate is faster than others that serve a somewhat similar purpose. Source? Trust me, bro.
Other similar crates: spanned-json-parser | jsonc-parser