Module rsonpath::classification::depth
source · 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::classification::quotes::classify_quoted_sequences;
use rsonpath::classification::depth::{
classify_depth, DepthIterator, DepthBlock
};
use rsonpath::classification::structural::BracketType;
use rsonpath::input::OwnedBytes;
use rsonpath::FallibleIterator;
let json = r#"[42, {"b":[[]],"c":{}}, 44]}"#.to_owned();
// ^^ ^
// AB C
let input = OwnedBytes::try_from(json).unwrap();
let quote_classifier = classify_quoted_sequences(&input);
// Goal: skip through the document until the end of the current list.
// We pass Square as the opening bracket type
// to tell the classifier to consider only '[' and ']' characters.
let mut depth_classifier = classify_depth(quote_classifier, BracketType::Square);
let mut depth_block = depth_classifier.next().unwrap().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::classification::depth::{classify_depth, DepthBlock, DepthIterator};
use rsonpath::classification::quotes::classify_quoted_sequences;
use rsonpath::classification::structural::BracketType;
use rsonpath::input::OwnedBytes;
use rsonpath::FallibleIterator;
let json = r#"
"a": [
42,
{
"b": {},
"c": {}
},
44
],
"b": {
"c": "value"
}
}{"target":true}"#.to_owned();
// We expect to reach the newline before the opening brace of the second object.
let expected_idx = json.len() - 15;
let input = OwnedBytes::try_from(json).unwrap();
let quote_classifier = classify_quoted_sequences(&input);
let mut depth_classifier = classify_depth(quote_classifier, BracketType::Curly);
let mut current_depth = 1;
while let Some(mut vector) = depth_classifier.next().unwrap() {
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
- The result of resuming a
DepthIterator
– the first block and the rest of the iterator.
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
- Enrich quote classified blocks with depth information.
- Resume classification using a state retrieved from a previously used classifier via the
stop
function.