use std::result::Result;
#[derive(Debug, PartialEq)]
pub enum ReaderError {
Eof,
}
pub struct PathReader<'a> {
input: &'a str,
pos: usize,
}
impl<'a> PathReader<'a> {
pub fn new(input: &'a str) -> Self {
PathReader { input, pos: 0 }
}
pub fn peek_char(&self) -> Result<(usize, char), ReaderError> {
let ch = self.input.chars().next().ok_or(ReaderError::Eof)?;
Ok((self.pos + ch.len_utf8(), ch))
}
pub fn take_while<F>(&mut self, fun: F) -> Result<(usize, String), ReaderError>
where
F: Fn(&char) -> bool,
{
let mut char_len: usize = 0;
let mut ret = String::new();
for c in self.input.chars().by_ref() {
if !fun(&c) {
break;
}
char_len += c.len_utf8();
ret.push(c);
}
self.pos += char_len;
self.input = &self.input[char_len..];
Ok((self.pos, ret))
}
pub fn next_char(&mut self) -> Result<(usize, char), ReaderError> {
let (_, ch) = self.peek_char()?;
self.input = &self.input[ch.len_utf8()..];
let ret = Ok((self.pos, ch));
self.pos += ch.len_utf8();
ret
}
pub fn current_pos(&self) -> usize {
self.pos
}
}