swc_html_parser/parser/
input.rs

1use std::{fmt::Debug, mem::take};
2
3use swc_atoms::Atom;
4use swc_common::{BytePos, Span};
5use swc_html_ast::{Token, TokenAndSpan};
6
7use super::PResult;
8use crate::{error::Error, lexer::State};
9
10pub trait ParserInput: Iterator<Item = TokenAndSpan> {
11    fn start_pos(&mut self) -> BytePos;
12
13    fn last_pos(&mut self) -> BytePos;
14
15    fn take_errors(&mut self) -> Vec<Error>;
16
17    fn set_last_start_tag_name(&mut self, tag_name: &Atom);
18
19    fn set_input_state(&mut self, state: State);
20
21    fn set_adjusted_current_node_to_html_namespace(&mut self, value: bool);
22}
23
24#[derive(Debug)]
25pub(super) struct Buffer<I>
26where
27    I: ParserInput,
28{
29    cur: Option<TokenAndSpan>,
30    input: I,
31}
32
33impl<I> Buffer<I>
34where
35    I: ParserInput,
36{
37    pub fn new(input: I) -> Self {
38        Buffer { cur: None, input }
39    }
40
41    /// Last start position
42    pub fn start_pos(&mut self) -> PResult<BytePos> {
43        Ok(self.input.start_pos())
44    }
45
46    /// Last end position
47    pub fn last_pos(&mut self) -> PResult<BytePos> {
48        Ok(self.input.last_pos())
49    }
50
51    pub fn cur_span(&mut self) -> PResult<Span> {
52        if self.cur.is_none() {
53            self.bump_inner()?;
54        }
55
56        Ok(self.cur.as_ref().map(|cur| cur.span).unwrap_or_default())
57    }
58
59    pub fn cur(&mut self) -> PResult<Option<&Token>> {
60        if self.cur.is_none() {
61            self.bump_inner()?;
62        }
63
64        Ok(self.cur.as_ref().map(|v| &v.token))
65    }
66
67    #[track_caller]
68    pub fn bump(&mut self) -> PResult<Option<TokenAndSpan>> {
69        debug_assert!(
70            self.cur.is_some(),
71            "bump() is called without checking current token"
72        );
73
74        let token = self.cur.take();
75
76        Ok(token)
77    }
78
79    fn bump_inner(&mut self) -> PResult<()> {
80        self.cur = None;
81
82        if self.cur.is_none() {
83            let result = self.input.next();
84
85            if let Some(result) = result {
86                self.cur = Some(result);
87            } else {
88                return Ok(());
89            }
90        }
91
92        Ok(())
93    }
94
95    pub fn take_errors(&mut self) -> Vec<Error> {
96        take(&mut self.input.take_errors())
97    }
98
99    pub(super) fn set_input_state(&mut self, state: State) {
100        self.input.set_input_state(state);
101    }
102
103    pub(super) fn set_adjusted_current_node_to_html_namespace(&mut self, value: bool) {
104        self.input
105            .set_adjusted_current_node_to_html_namespace(value);
106    }
107}