pest/iterators/
tokens.rs
1use alloc::rc::Rc;
11use alloc::vec::Vec;
12use core::fmt;
13use core::str;
14
15use super::queueable_token::QueueableToken;
16use crate::position;
17use crate::token::Token;
18use crate::RuleType;
19
20#[derive(Clone)]
26pub struct Tokens<'i, R> {
27 queue: Rc<Vec<QueueableToken<'i, R>>>,
28 input: &'i str,
29 start: usize,
30 end: usize,
31}
32
33pub fn new<'i, R: RuleType>(
34 queue: Rc<Vec<QueueableToken<'i, R>>>,
35 input: &'i str,
36 start: usize,
37 end: usize,
38) -> Tokens<'i, R> {
39 if cfg!(debug_assertions) {
40 for tok in queue.iter() {
41 match *tok {
42 QueueableToken::Start { input_pos, .. } | QueueableToken::End { input_pos, .. } => {
43 assert!(
44 input.get(input_pos..).is_some(),
45 "💥 INVALID `Tokens` CREATED 💥"
46 )
47 }
48 }
49 }
50 }
51
52 Tokens {
53 queue,
54 input,
55 start,
56 end,
57 }
58}
59
60impl<'i, R: RuleType> Tokens<'i, R> {
61 fn create_token(&self, index: usize) -> Token<'i, R> {
62 match self.queue[index] {
63 QueueableToken::Start {
64 end_token_index,
65 input_pos,
66 } => {
67 let rule = match self.queue[end_token_index] {
68 QueueableToken::End { rule, .. } => rule,
69 _ => unreachable!(),
70 };
71
72 Token::Start {
73 rule,
74 pos: position::Position::new_internal(self.input, input_pos),
75 }
76 }
77 QueueableToken::End {
78 rule, input_pos, ..
79 } => Token::End {
80 rule,
81 pos: position::Position::new_internal(self.input, input_pos),
82 },
83 }
84 }
85}
86
87impl<'i, R: RuleType> ExactSizeIterator for Tokens<'i, R> {
88 fn len(&self) -> usize {
89 self.end - self.start
90 }
91}
92
93impl<'i, R: RuleType> Iterator for Tokens<'i, R> {
94 type Item = Token<'i, R>;
95
96 fn next(&mut self) -> Option<Self::Item> {
97 if self.start >= self.end {
98 return None;
99 }
100
101 let token = self.create_token(self.start);
102
103 self.start += 1;
104
105 Some(token)
106 }
107
108 fn size_hint(&self) -> (usize, Option<usize>) {
109 let len = <Self as ExactSizeIterator>::len(self);
110 (len, Some(len))
111 }
112}
113
114impl<'i, R: RuleType> DoubleEndedIterator for Tokens<'i, R> {
115 fn next_back(&mut self) -> Option<Self::Item> {
116 if self.end <= self.start {
117 return None;
118 }
119
120 let token = self.create_token(self.end - 1);
121
122 self.end -= 1;
123
124 Some(token)
125 }
126}
127
128impl<'i, R: RuleType> fmt::Debug for Tokens<'i, R> {
129 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
130 f.debug_list().entries(self.clone()).finish()
131 }
132}
133
134#[cfg(test)]
135mod tests {
136 use super::super::super::macros::tests::*;
137 use super::super::super::Parser;
138 use super::Token;
139 use alloc::vec::Vec;
140
141 #[test]
142 fn double_ended_iter_for_tokens() {
143 let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();
144 let mut tokens = pairs.clone().tokens().collect::<Vec<Token<'_, Rule>>>();
145 tokens.reverse();
146 let reverse_tokens = pairs.tokens().rev().collect::<Vec<Token<'_, Rule>>>();
147 assert_eq!(tokens, reverse_tokens);
148 }
149
150 #[test]
151 fn exact_size_iter_for_tokens() {
152 let tokens = AbcParser::parse(Rule::a, "abcde").unwrap().tokens();
153 assert_eq!(tokens.len(), tokens.count());
154
155 let tokens = AbcParser::parse(Rule::a, "我很漂亮e").unwrap().tokens();
156 assert_eq!(tokens.len(), tokens.count());
157
158 let tokens = AbcParser::parse(Rule::a, "abcde").unwrap().tokens().rev();
159 assert_eq!(tokens.len(), tokens.count());
160
161 let mut tokens = AbcParser::parse(Rule::a, "abcde").unwrap().tokens();
162 let tokens_len = tokens.len();
163 let _ = tokens.next().unwrap();
164 assert_eq!(tokens.count() + 1, tokens_len);
165 }
166}