ass_core/tokenizer/
ass_tokenizer.rs1use super::{IssueCollector, Token, TokenContext, TokenIssue, TokenScanner};
8use crate::Result;
9use alloc::vec::Vec;
10
11#[cfg(not(feature = "std"))]
12extern crate alloc;
13
14#[derive(Debug, Clone)]
19pub struct AssTokenizer<'a> {
20 pub(super) source: &'a str,
22 pub(super) scanner: TokenScanner<'a>,
24 pub(super) context: TokenContext,
26 issues: IssueCollector<'a>,
28}
29
30impl<'a> AssTokenizer<'a> {
31 #[must_use]
35 pub fn new(source: &'a str) -> Self {
36 let initial_position = if source.starts_with('\u{FEFF}') {
37 3 } else {
39 0
40 };
41
42 Self {
43 source,
44 scanner: TokenScanner::new(source, initial_position, 1, 1),
45 context: TokenContext::Document,
46 issues: IssueCollector::new(),
47 }
48 }
49
50 pub fn tokenize_all(&mut self) -> Result<Vec<Token<'a>>> {
56 let mut tokens = Vec::new();
57 let mut iteration_count = 0;
58 while let Some(token) = self.next_token()? {
59 tokens.push(token);
60 iteration_count += 1;
61 if iteration_count > 50 {
62 return Err(crate::utils::CoreError::internal(
63 "Too many tokenizer iterations",
64 ));
65 }
66 }
67
68 Ok(tokens)
69 }
70
71 #[must_use]
73 pub fn issues(&self) -> &[TokenIssue<'a>] {
74 self.issues.issues()
75 }
76
77 #[must_use]
79 pub const fn position(&self) -> usize {
80 self.scanner.navigator().position()
81 }
82
83 #[must_use]
85 pub const fn line(&self) -> usize {
86 self.scanner.navigator().line()
87 }
88
89 #[must_use]
91 pub const fn column(&self) -> usize {
92 self.scanner.navigator().column()
93 }
94
95 pub fn reset(&mut self) {
97 let initial_position = if self.source.starts_with('\u{FEFF}') {
98 3
99 } else {
100 0
101 };
102 self.scanner = TokenScanner::new(self.source, initial_position, 1, 1);
103 self.context = TokenContext::Document;
104 self.issues.clear();
105 }
106}