Crate rsonpath_lib

source ·
Expand description

Blazing fast execution of JSONPath queries.

JSONPath parser, execution engines and byte stream utilities useful when parsing JSON structures.

Examples

use rsonpath_lib::engine::{Input, Runner, result::CountResult};
use rsonpath_lib::query::JsonPathQuery;
use rsonpath_lib::stackless::StacklessRunner;

// Parse a JSONPath query from string.
let query = JsonPathQuery::parse("$..person..number")?;
let contents = r#"
{
  "person": {
    "name": "John",
    "surname": "Doe",
    "phoneNumbers": [
      {
        "type": "Home",
        "number": "111-222-333"
      },
      {
        "type": "Work",
        "number": "123-456-789"
      }
    ]
  }
}
"#;
// Remove whitespace from the JSON - limitation of the current version.
let mut stripped_contents = contents.chars().filter(|c| !c.is_whitespace()).collect::<String>();
// Convert the contents to the Input type required by the Runners.
let input = Input::new(&mut stripped_contents);
// Compile the query. The runner can be reused to run the same query on different contents.
let runner = StacklessRunner::compile_query(&query)?;
// Count the number of occurrences of elements satisfying the query.
let count = runner.run::<CountResult>(&input)?.get();

assert_eq!(2, count);

Input JSON assumptions

  1. The JSON must be a syntactically valid JSON encoded in UTF-8 as defined by RFC4627.
  2. The JSON must not contain any whitespace outside of string values. This is a known limitation that will be lifted in future versions.

If the assumptions are violated the algorithm’s behavior is undefined. It might panic or it might return nonsensical results. No validation is performed for maximum performance. Asserting the assumptions falls on the user of this library.

JSONPath language

The library implements the JSONPath syntax as established by Stefan Goessner in https://goessner.net/articles/JsonPath/. That implementation does not describe its semantics. There is no guarantee that this library has the same semantics as Goessner’s implementation. The semantics used by rsonpath are described below.

Grammar

query = [root_expr] , { expr }
expr = root_expr | descendant_expr | label_expr
root_expr = "$"
descendant_expr = ".."
label_expr = simple_label | explicit_label
simple_label = { ALPHANUMERIC | "_" }
explicit_label = "['" , JSON_LABEL , "']"

ALPHANUMERIC = [A-Z][a-z][0-9]

JSON_LABEL is the string defined by RFC4627.

Semantics

The query is executed from left to right, expression by expression. When a value is found that matches the current expression, the execution advances to the next expression and evaluates it recursively within the context of that value.

Root expression

The root expression may only appear at the beginning of the query and is implicit if not specified. It matches the root object or array. Thus the query “$” gives either 1 or 0 results, if the JSON is empty or non-empty, respectively.

Label expression

Matches any value under a specified key in the current object or array and then executes the rest of the query on that value.

Descendant expression

Switches the engine into a recursive descent mode. The remainder of the query is executed recursively on every value nested in the current object or array.

Limitations

The only type of query supported as of now is a sequence of descendant-label expressions.

$..label_1..label_2..[...]..label_n

Modules

Classification of structurally significant JSON bytes.
JSON depth calculations on byte streams.
Base traits for different implementations of JSONPath execution engines.
Common errors shared across the library.
Defines JSONPath query structure and parsing logic.
Classification of bytes withing JSON quote sequences.
Reference implementation of a JSONPath query engine with recursive descent.
Stackless implementation of a JSONPath query engine.

Macros

Debug log the given u64 expression by its full 64-bit binary string representation.
Macro for debug logging. Evaluates to log::debug, if debug assertions are enabled. Otherwise it’s an empty statement.

Type Definitions

Default alignment required out of input blocks for the purpose of classification with quotes and classify.