1use alloc::format;
11use alloc::rc::Rc;
12use alloc::string::String;
13use alloc::vec::Vec;
14use std::fmt;
15use std::hash::{Hash, Hasher};
16use std::str;
17use std::sync::Arc;
18
19#[cfg(feature = "pretty-print")]
20use serde::ser::SerializeStruct;
21
22use super::flat_pairs::{self, FlatPairs};
23use super::pair::{self, Pair};
24use super::queueable_token::QueueableToken;
25use super::tokens::{self, Tokens};
26use RuleType;
27
28#[derive(Clone)]
34pub struct Pairs<R> {
35 queue: Rc<Vec<QueueableToken<R>>>,
36 input: Arc<str>,
37 start: usize,
38 end: usize,
39}
40
41pub fn new<R: RuleType>(
42 queue: Rc<Vec<QueueableToken<R>>>,
43 input: Arc<str>,
44 start: usize,
45 end: usize,
46) -> Pairs<R> {
47 Pairs {
48 queue,
49 input,
50 start,
51 end,
52 }
53}
54
55impl<R: RuleType> Pairs<R> {
56 #[inline]
83 pub fn as_str(&self) -> &str {
84 if self.start < self.end {
85 let start = self.pos(self.start);
86 let end = self.pos(self.end - 1);
87 &self.input[start..end]
89 } else {
90 ""
91 }
92 }
93
94 #[inline]
120 pub fn concat(&self) -> String {
121 self.clone()
122 .fold(String::new(), |string, pair| string + pair.as_str())
123 }
124
125 #[inline]
152 pub fn flatten(self) -> FlatPairs<R> {
153 unsafe { flat_pairs::new(self.queue, self.input, self.start, self.end) }
154 }
155
156 #[inline]
180 pub fn tokens(self) -> Tokens<R> {
181 tokens::new(self.queue, self.input, self.start, self.end)
182 }
183
184 #[inline]
186 pub fn peek(&self) -> Option<Pair<R>> {
187 if self.start < self.end {
188 Some(unsafe { pair::new(Rc::clone(&self.queue), self.input.clone(), self.start) })
189 } else {
190 None
191 }
192 }
193
194 #[cfg(feature = "pretty-print")]
197 pub fn to_json(&self) -> String {
198 ::serde_json::to_string_pretty(self).expect("Failed to pretty-print Pairs to json.")
199 }
200
201 fn pair(&self) -> usize {
202 match self.queue[self.start] {
203 QueueableToken::Start {
204 end_token_index, ..
205 } => end_token_index,
206 _ => unreachable!(),
207 }
208 }
209
210 fn pair_from_end(&self) -> usize {
211 match self.queue[self.end - 1] {
212 QueueableToken::End {
213 start_token_index, ..
214 } => start_token_index,
215 _ => unreachable!(),
216 }
217 }
218
219 fn pos(&self, index: usize) -> usize {
220 match self.queue[index] {
221 QueueableToken::Start { input_pos, .. } | QueueableToken::End { input_pos, .. } => {
222 input_pos
223 }
224 }
225 }
226}
227
228impl<R: RuleType> Iterator for Pairs<R> {
229 type Item = Pair<R>;
230
231 fn next(&mut self) -> Option<Self::Item> {
232 let pair = self.peek()?;
233 self.start = self.pair() + 1;
234 Some(pair)
235 }
236}
237
238impl<R: RuleType> DoubleEndedIterator for Pairs<R> {
239 fn next_back(&mut self) -> Option<Self::Item> {
240 if self.end <= self.start {
241 return None;
242 }
243
244 self.end = self.pair_from_end();
245
246 let pair = unsafe { pair::new(Rc::clone(&self.queue), self.input.clone(), self.end) };
247
248 Some(pair)
249 }
250}
251
252impl<R: RuleType> fmt::Debug for Pairs<R> {
253 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
254 f.debug_list().entries(self.clone()).finish()
255 }
256}
257
258impl<R: RuleType> fmt::Display for Pairs<R> {
259 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
260 write!(
261 f,
262 "[{}]",
263 self.clone()
264 .map(|pair| format!("{}", pair))
265 .collect::<Vec<_>>()
266 .join(", ")
267 )
268 }
269}
270
271impl<R: PartialEq> PartialEq for Pairs<R> {
272 fn eq(&self, other: &Pairs<R>) -> bool {
273 Rc::ptr_eq(&self.queue, &other.queue)
274 && Arc::ptr_eq(&self.input, &other.input)
275 && self.start == other.start
276 && self.end == other.end
277 }
278}
279
280impl<R: Eq> Eq for Pairs<R> {}
281
282impl<R: Hash> Hash for Pairs<R> {
283 fn hash<H: Hasher>(&self, state: &mut H) {
284 (&*self.queue as *const Vec<QueueableToken<R>>).hash(state);
285 Arc::as_ptr(&self.input).hash(state);
286 self.start.hash(state);
287 self.end.hash(state);
288 }
289}
290
291#[cfg(feature = "pretty-print")]
292impl<R: RuleType> ::serde::Serialize for Pairs<R> {
293 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
294 where
295 S: ::serde::Serializer,
296 {
297 let start = self.pos(self.start);
298 let end = self.pos(self.end - 1);
299 let pairs = self.clone().collect::<Vec<_>>();
300
301 let mut ser = serializer.serialize_struct("Pairs", 2)?;
302 ser.serialize_field("pos", &(start, end))?;
303 ser.serialize_field("pairs", &pairs)?;
304 ser.end()
305 }
306}
307
308#[cfg(test)]
309mod tests {
310 use super::super::super::macros::tests::*;
311 use super::super::super::Parser;
312 use alloc::borrow::ToOwned;
313 use alloc::format;
314 use alloc::vec;
315 use alloc::vec::Vec;
316 use std::sync::Arc;
317
318 #[test]
319 #[cfg(feature = "pretty-print")]
320 fn test_pretty_print() {
321 let pairs = AbcParser::parse(Rule::a, Arc::from("abcde")).unwrap();
322
323 let expected = r#"{
324 "pos": [
325 0,
326 5
327 ],
328 "pairs": [
329 {
330 "pos": [
331 0,
332 3
333 ],
334 "rule": "a",
335 "inner": {
336 "pos": [
337 1,
338 2
339 ],
340 "pairs": [
341 {
342 "pos": [
343 1,
344 2
345 ],
346 "rule": "b",
347 "inner": "b"
348 }
349 ]
350 }
351 },
352 {
353 "pos": [
354 4,
355 5
356 ],
357 "rule": "c",
358 "inner": "e"
359 }
360 ]
361}"#;
362
363 assert_eq!(expected, pairs.to_json());
364 }
365
366 #[test]
367 fn as_str() {
368 let pairs = AbcParser::parse(Rule::a, Arc::from("abcde")).unwrap();
369
370 assert_eq!(pairs.as_str(), "abcde");
371 }
372
373 #[test]
374 fn as_str_empty() {
375 let mut pairs = AbcParser::parse(Rule::a, Arc::from("abcde")).unwrap();
376
377 assert_eq!(pairs.nth(1).unwrap().into_inner().as_str(), "");
378 }
379
380 #[test]
381 fn concat() {
382 let pairs = AbcParser::parse(Rule::a, Arc::from("abcde")).unwrap();
383
384 assert_eq!(pairs.concat(), "abce");
385 }
386
387 #[test]
388 fn pairs_debug() {
389 let pairs = AbcParser::parse(Rule::a, Arc::from("abcde")).unwrap();
390
391 #[rustfmt::skip]
392 assert_eq!(
393 format!("{:?}", pairs),
394 "[\
395 Pair { rule: a, span: Span { str: \"abc\", start: 0, end: 3 }, inner: [\
396 Pair { rule: b, span: Span { str: \"b\", start: 1, end: 2 }, inner: [] }\
397 ] }, \
398 Pair { rule: c, span: Span { str: \"e\", start: 4, end: 5 }, inner: [] }\
399 ]"
400 .to_owned()
401 );
402 }
403
404 #[test]
405 fn pairs_display() {
406 let pairs = AbcParser::parse(Rule::a, Arc::from("abcde")).unwrap();
407
408 assert_eq!(
409 format!("{}", pairs),
410 "[a(0, 3, [b(1, 2)]), c(4, 5)]".to_owned()
411 );
412 }
413
414 #[test]
415 fn iter_for_pairs() {
416 let pairs = AbcParser::parse(Rule::a, Arc::from("abcde")).unwrap();
417 assert_eq!(
418 pairs.map(|p| p.as_rule()).collect::<Vec<Rule>>(),
419 vec![Rule::a, Rule::c]
420 );
421 }
422
423 #[test]
424 fn double_ended_iter_for_pairs() {
425 let pairs = AbcParser::parse(Rule::a, Arc::from("abcde")).unwrap();
426 assert_eq!(
427 pairs.rev().map(|p| p.as_rule()).collect::<Vec<Rule>>(),
428 vec![Rule::c, Rule::a]
429 );
430 }
431}