Expand description

JSON depth calculations on byte streams.

Used for iterating over the document while keeping track of depth. This is heavily optimized for skipping irrelevant parts of a JSON document. For example, to quickly skip to the end of the currently opened object one can set the depth to 1 and then advance until it reaches 0.

It also supports stopping and resuming with ResumeClassifierState.

Examples

Illustrating how the skipping works:

use rsonpath_lib::classification::quotes::classify_quoted_sequences;
use rsonpath_lib::classification::depth::{
    classify_depth, DepthIterator, DepthBlock
};
use aligners::AlignedBytes;

let input = AlignedBytes::new_padded(r#"[42, {"b":[[]],"c":{}}, 44]}"#.as_bytes());
// Name a few places in the input:                  ^^            ^
//                                                  AB            C
let quote_classifier = classify_quoted_sequences(&input);
// Goal: skip through the document until the end of the current list.
// We pass b'[' as the opening to tell the classifier to consider only '[' and ']' characters.
let mut depth_classifier = classify_depth(quote_classifier, b'[');
let mut depth_block = depth_classifier.next().unwrap();

assert_eq!(depth_block.get_depth(), 0);
assert!(depth_block.advance_to_next_depth_decrease()); // Advances to A.
assert_eq!(depth_block.get_depth(), 2);
assert!(depth_block.advance_to_next_depth_decrease()); // Advances to B.
assert_eq!(depth_block.get_depth(), 1);
assert!(depth_block.advance_to_next_depth_decrease()); // Advances to C.
assert_eq!(depth_block.get_depth(), 0);
// Skipping complete.

Idiomatic usage for a high-performance skipping loop:

use rsonpath_lib::classification::depth::{classify_depth, DepthBlock, DepthIterator};
use rsonpath_lib::classification::quotes::classify_quoted_sequences;
use aligners::AlignedBytes;

let json = r#"
    "a": [
        42,
        {
            "b": {},
            "c": {}
        },
        44
    ],
    "b": {
        "c": "value"
    }
}{"target":true}"#;
let input = AlignedBytes::new_padded(json.as_bytes());
// We expect to reach the newline before the opening brace of the second object.
let expected_idx = json.len() - 15;
let quote_classifier = classify_quoted_sequences(&input);
let mut depth_classifier = classify_depth(quote_classifier, b'{');
let mut current_depth = 1;

while let Some(mut vector) = depth_classifier.next() {
    vector.add_depth(current_depth);

    if vector.estimate_lowest_possible_depth() <= 0 {
        while vector.advance_to_next_depth_decrease() {
            if vector.get_depth() == 0 {
                let stop_state = depth_classifier.stop(Some(vector));
                assert_eq!(stop_state.get_idx(), expected_idx);
                return;
            }
        }
    }

    current_depth = vector.depth_at_end();
}
unreachable!();

Structs

Traits

  • Common trait for structs that enrich a byte block with JSON depth information.
  • Trait for depth iterators, i.e. finite iterators returning depth information about JSON documents.

Functions