rsonpath/classification/structural/
shared.rs1#[cfg(target_arch = "x86")]
2pub(super) mod mask_32;
3#[cfg(target_arch = "x86_64")]
4pub(super) mod mask_64;
5#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
6pub(super) mod vector_128;
7#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
8pub(super) mod vector_256;
9
10#[allow(unused_macros)]
11macro_rules! structural_classifier {
12 ($name:ident, $core:ident, $mask_mod:ident, $size:literal, $mask_ty:ty) => {
13 pub(crate) struct Constructor;
14
15 impl StructuralImpl for Constructor {
16 type Classifier<'i, I, Q>
17 = $name<'i, I, Q>
18 where
19 I: InputBlockIterator<'i, BLOCK_SIZE>,
20 Q: QuoteClassifiedIterator<'i, I, MaskType, BLOCK_SIZE>;
21
22 #[inline]
23 #[allow(dead_code)]
24 fn new<'i, I, Q>(iter: Q) -> Self::Classifier<'i, I, Q>
25 where
26 I: InputBlockIterator<'i, BLOCK_SIZE>,
27 Q: QuoteClassifiedIterator<'i, I, MaskType, BLOCK_SIZE>,
28 {
29 Self::Classifier {
30 iter,
31 classifier: $core::new(),
32 block: None,
33 are_commas_on: false,
34 are_colons_on: false,
35 }
36 }
37 }
38
39 pub(crate) struct $name<'a, I, Q>
40 where
41 I: InputBlockIterator<'a, $size>,
42 {
43 iter: Q,
44 classifier: $core,
45 block: Option<$mask_mod::StructuralsBlock<I::Block>>,
46 are_commas_on: bool,
47 are_colons_on: bool,
48 }
49
50 impl<'a, I: InputBlockIterator<'a, $size>, Q: QuoteClassifiedIterator<'a, I, $mask_ty, $size>> $name<'a, I, Q> {
51 #[inline(always)]
52 fn current_block_is_spent(&self) -> bool {
53 self.block
54 .as_ref()
55 .map_or(true, $mask_mod::StructuralsBlock::is_empty)
56 }
57
58 #[inline]
59 fn reclassify(&mut self, idx: usize) {
60 if let Some(block) = self.block.take() {
61 let quote_classified_block = block.quote_classified;
62 let relevant_idx = idx + 1;
63 let block_idx = (idx + 1) % $size;
64 debug!("relevant_idx is {relevant_idx}.");
65
66 if block_idx != 0 || relevant_idx == self.iter.get_offset() {
67 debug!("need to reclassify.");
68
69 let mask = <$mask_ty>::MAX << block_idx;
70 let mut new_block = unsafe { self.classifier.classify(quote_classified_block) };
72 new_block.structural_mask &= mask;
73 self.block = Some(new_block);
74 }
75 }
76 }
77 }
78
79 impl<'a, I, Q> FallibleIterator for $name<'a, I, Q>
80 where
81 I: InputBlockIterator<'a, $size>,
82 Q: QuoteClassifiedIterator<'a, I, $mask_ty, $size>,
83 {
84 type Item = Structural;
85 type Error = InputError;
86
87 #[inline(always)]
88 fn next(&mut self) -> Result<Option<Structural>, Self::Error> {
89 while self.current_block_is_spent() {
90 match self.iter.next() {
91 Ok(Some(block)) => {
92 self.block = unsafe { Some(self.classifier.classify(block)) };
94 }
95 Ok(None) => {
96 self.block = None;
97 break;
98 }
99 Err(err) => return Err(err),
100 }
101 }
102
103 Ok(self
104 .block
105 .as_mut()
106 .and_then(|b| b.next().map(|x| x.offset(self.iter.get_offset()))))
107 }
108 }
109
110 impl<'a, I, Q> StructuralIterator<'a, I, Q, $mask_ty, $size> for $name<'a, I, Q>
111 where
112 I: InputBlockIterator<'a, $size>,
113 Q: QuoteClassifiedIterator<'a, I, $mask_ty, $size>,
114 {
115 #[inline(always)]
116 fn turn_colons_and_commas_on(&mut self, idx: usize) {
117 if !self.are_commas_on && !self.are_colons_on {
118 self.are_commas_on = true;
119 self.are_colons_on = true;
120 debug!("Turning both commas and colons on at {idx}.");
121 unsafe { self.classifier.internal_classifier.toggle_colons_and_commas() }
123
124 self.reclassify(idx);
125 } else if !self.are_commas_on {
126 self.turn_commas_on(idx);
127 } else if !self.are_colons_on {
128 self.turn_colons_on(idx);
129 }
130 }
131
132 #[inline(always)]
133 fn turn_colons_and_commas_off(&mut self) {
134 if self.are_commas_on && self.are_colons_on {
135 self.are_commas_on = false;
136 self.are_colons_on = false;
137 debug!("Turning both commas and colons off.");
138 unsafe { self.classifier.internal_classifier.toggle_colons_and_commas() }
140 } else if self.are_commas_on {
141 self.turn_commas_off();
142 } else if self.are_colons_on {
143 self.turn_colons_off();
144 }
145 }
146
147 #[inline(always)]
148 fn turn_commas_on(&mut self, idx: usize) {
149 if !self.are_commas_on {
150 self.are_commas_on = true;
151 debug!("Turning commas on at {idx}.");
152 unsafe { self.classifier.internal_classifier.toggle_commas() }
154
155 self.reclassify(idx);
156 }
157 }
158
159 #[inline(always)]
160 fn turn_commas_off(&mut self) {
161 if self.are_commas_on {
162 self.are_commas_on = false;
163 debug!("Turning commas off.");
164 unsafe { self.classifier.internal_classifier.toggle_commas() }
166 }
167 }
168
169 #[inline(always)]
170 fn turn_colons_on(&mut self, idx: usize) {
171 if !self.are_colons_on {
172 self.are_colons_on = true;
173 debug!("Turning colons on at {idx}.");
174 unsafe { self.classifier.internal_classifier.toggle_colons() }
176
177 self.reclassify(idx);
178 }
179 }
180
181 #[inline(always)]
182 fn turn_colons_off(&mut self) {
183 if self.are_colons_on {
184 self.are_colons_on = false;
185 debug!("Turning colons off.");
186 unsafe { self.classifier.internal_classifier.toggle_colons() }
188 }
189 }
190
191 #[inline(always)]
192 fn stop(self) -> ResumeClassifierState<'a, I, Q, $mask_ty, $size> {
193 let block = self.block.map(|b| ResumeClassifierBlockState {
194 idx: b.get_idx() as usize,
195 block: b.quote_classified,
196 });
197
198 ResumeClassifierState {
199 iter: self.iter,
200 block,
201 are_commas_on: self.are_commas_on,
202 are_colons_on: self.are_colons_on,
203 }
204 }
205
206 #[inline(always)]
207 fn resume(state: ResumeClassifierState<'a, I, Q, $mask_ty, $size>) -> Self {
208 let mut classifier = $core::new();
209
210 unsafe {
212 if state.are_commas_on && state.are_colons_on {
213 classifier.internal_classifier.toggle_colons_and_commas();
214 } else {
215 if state.are_commas_on {
216 classifier.internal_classifier.toggle_commas();
217 }
218 if state.are_colons_on {
219 classifier.internal_classifier.toggle_colons();
220 }
221 }
222 }
223
224 let block = state.block.map(|b| {
225 let mut block = unsafe { classifier.classify(b.block) };
227 let idx_mask = <$mask_ty>::MAX.checked_shl(b.idx as u32).unwrap_or(0);
228 block.structural_mask &= idx_mask;
229
230 block
231 });
232
233 Self {
234 iter: state.iter,
235 block,
236 classifier,
237 are_commas_on: state.are_commas_on,
238 are_colons_on: state.are_colons_on,
239 }
240 }
241 }
242 };
243}
244
245#[allow(unused_imports)]
246pub(crate) use structural_classifier;