use std::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::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::Result<(usize, Vec<char>), ReaderError>
where
F: Fn(&char) -> bool
{
let vec: Vec<char> = self.input.chars()
.by_ref()
.take_while(fun)
.collect();
let char_len: usize = vec.iter().by_ref().map(|c| c.len_utf8()).sum();
self.pos += char_len;
self.input = &self.input[char_len..];
Ok((self.pos, vec))
}
pub fn next_char(&mut self) -> result::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
}
}