Skip to main content

oni_comb_parser/
str_input.rs

1use crate::input::Input;
2
3pub struct StrInput<'a> {
4  src: &'a str,
5  offset: usize,
6}
7
8impl<'a> StrInput<'a> {
9  pub fn new(src: &'a str) -> Self {
10    Self { src, offset: 0 }
11  }
12
13  pub(crate) fn advance(&mut self, n: usize) {
14    self.offset += n;
15  }
16
17  pub(crate) fn as_str(&self) -> &'a str {
18    &self.src[self.offset..]
19  }
20
21  /// 次のバイトを消費せずに覗く。EOF なら `None`。
22  #[inline]
23  pub fn peek_byte(&self) -> Option<u8> {
24    self.src.as_bytes().get(self.offset).copied()
25  }
26}
27
28impl<'a> Input for StrInput<'a> {
29  type Checkpoint = usize;
30  #[cfg(feature = "alloc")]
31  type Error = crate::error::ParseError;
32  #[cfg(not(feature = "alloc"))]
33  type Error = crate::error::MinimalError;
34  type Slice = &'a str;
35  type Token = char;
36
37  #[inline]
38  fn next_token(&mut self) -> Option<char> {
39    let b = *self.src.as_bytes().get(self.offset)?;
40    if b.is_ascii() {
41      self.offset += 1;
42      return Some(b as char);
43    }
44
45    let c = self.as_str().chars().next()?;
46    self.offset += c.len_utf8();
47    Some(c)
48  }
49
50  #[inline]
51  fn peek_token(&self) -> Option<char> {
52    let b = *self.src.as_bytes().get(self.offset)?;
53    if b.is_ascii() {
54      return Some(b as char);
55    }
56
57    self.as_str().chars().next()
58  }
59
60  #[inline]
61  fn slice_since(&self, cp: usize) -> &'a str {
62    &self.src[cp..self.offset]
63  }
64
65  fn checkpoint(&self) -> Self::Checkpoint {
66    self.offset
67  }
68
69  fn reset(&mut self, checkpoint: Self::Checkpoint) {
70    self.offset = checkpoint;
71  }
72
73  fn offset(&self) -> usize {
74    self.offset
75  }
76
77  fn remaining(&self) -> &'a str {
78    &self.src[self.offset..]
79  }
80
81  fn is_eof(&self) -> bool {
82    self.offset >= self.src.len()
83  }
84}