1use std::result::Result;
2
3#[derive(Debug, PartialEq)]
4pub enum ReaderError {
5 Eof,
6}
7
8pub struct PathReader<'a> {
9 input: &'a str,
10 pos: usize,
11}
12
13impl<'a> PathReader<'a> {
14 pub fn new(input: &'a str) -> Self {
15 PathReader { input, pos: 0 }
16 }
17
18 pub fn peek_char(&self) -> Result<(usize, char), ReaderError> {
19 let ch = self.input.chars().next().ok_or(ReaderError::Eof)?;
20 Ok((self.pos + ch.len_utf8(), ch))
21 }
22
23 pub fn take_while<F>(&mut self, fun: F) -> Result<(usize, String), ReaderError>
24 where
25 F: Fn(&char) -> bool,
26 {
27 let mut char_len: usize = 0;
28 let mut ret = String::new();
29 for c in self.input.chars().by_ref() {
30 if !fun(&c) {
31 break;
32 }
33 char_len += c.len_utf8();
34 ret.push(c);
35 }
36
37 self.pos += char_len;
38 self.input = &self.input[char_len..];
39 Ok((self.pos, ret))
40 }
41
42 pub fn next_char(&mut self) -> Result<(usize, char), ReaderError> {
43 let (_, ch) = self.peek_char()?;
44 self.input = &self.input[ch.len_utf8()..];
45 let ret = Ok((self.pos, ch));
46 self.pos += ch.len_utf8();
47 ret
48 }
49
50 pub fn current_pos(&self) -> usize {
51 self.pos
52 }
53}
54