1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
//! 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:
//! ```rust
//! use rsonpath::classification::quotes::classify_quoted_sequences;
//! use rsonpath::classification::depth::{
//! classify_depth, DepthIterator, DepthBlock
//! };
//! use rsonpath::classification::structural::BracketType;
//! use rsonpath::input::{Input, OwnedBytes};
//! use rsonpath::result::empty::EmptyRecorder;
//! use rsonpath::FallibleIterator;
//!
//! let json = r#"[42, {"b":[[]],"c":{}}, 44]}"#.to_owned();
//! // ^^ ^
//! // AB C
//! let input = OwnedBytes::try_from(json).unwrap();
//! let iter = input.iter_blocks::<_, 64>(&EmptyRecorder);
//! let quote_classifier = classify_quoted_sequences(iter);
//! // 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:
//! ```rust
//! use rsonpath::classification::depth::{classify_depth, DepthBlock, DepthIterator};
//! use rsonpath::classification::quotes::classify_quoted_sequences;
//! use rsonpath::classification::structural::BracketType;
//! use rsonpath::input::{Input, OwnedBytes};
//! use rsonpath::result::empty::EmptyRecorder;
//! 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 iter = input.iter_blocks::<_, 64>(&EmptyRecorder);
//! let quote_classifier = classify_quoted_sequences(iter);
//! 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!();
//! ```
//!
use BracketType;
use crate::;
use cfg_if;
/// 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.
/// The result of resuming a [`DepthIterator`] – the first block and the rest of the iterator.
where
I: ,
D: ;
cfg_if!
/// Enrich quote classified blocks with depth information.
/// Resume classification using a state retrieved from a previously
/// used classifier via the `stop` function.