1 | use std::result::Result; |
2 | |
3 | #[derive (Debug, PartialEq)] |
4 | pub enum ReaderError { |
5 | Eof, |
6 | } |
7 | |
8 | pub struct PathReader<'a> { |
9 | input: &'a str, |
10 | pos: usize, |
11 | } |
12 | |
13 | impl<'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 | |