Skip to content

cyruspyre/flexon

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

50 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

flexon crates.io

A JSON parser with span tracking and optional comment support.

Example

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());

Features

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.

Performance

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

About

A fast, flexible JSON parser for Rust

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages