use std::ops;
use char::Char;
use literals::Literals;
#[derive(Clone, Copy, Debug)]
pub struct InputAt {
pos: usize,
c: Char,
byte: Option<u8>,
len: usize,
}
impl InputAt {
pub fn is_start(&self) -> bool {
self.pos == 0
}
pub fn is_end(&self) -> bool {
self.c.is_none() && self.byte.is_none()
}
pub fn char(&self) -> Char {
self.c
}
pub fn byte(&self) -> Option<u8> {
self.byte
}
pub fn len(&self) -> usize {
self.len
}
pub fn pos(&self) -> usize {
self.pos
}
pub fn next_pos(&self) -> usize {
self.pos + self.len
}
}
pub trait Input {
fn at(&self, i: usize) -> InputAt;
fn next_char(&self, at: InputAt) -> Char;
fn previous_char(&self, at: InputAt) -> Char;
fn prefix_at(&self, prefixes: &Literals, at: InputAt) -> Option<InputAt>;
fn len(&self) -> usize;
fn as_bytes(&self) -> &[u8];
}
impl<'a, T: Input> Input for &'a T {
fn at(&self, i: usize) -> InputAt { (**self).at(i) }
fn next_char(&self, at: InputAt) -> Char { (**self).next_char(at) }
fn previous_char(&self, at: InputAt) -> Char { (**self).previous_char(at) }
fn prefix_at(&self, prefixes: &Literals, at: InputAt) -> Option<InputAt> {
(**self).prefix_at(prefixes, at)
}
fn len(&self) -> usize { (**self).len() }
fn as_bytes(&self) -> &[u8] { (**self).as_bytes() }
}
#[derive(Clone, Copy, Debug)]
pub struct CharInput<'t>(&'t str);
impl<'t> CharInput<'t> {
pub fn new(s: &'t str) -> CharInput<'t> {
CharInput(s)
}
}
impl<'t> ops::Deref for CharInput<'t> {
type Target = str;
fn deref(&self) -> &str {
self.0
}
}
impl<'t> Input for CharInput<'t> {
#[inline(always)]
fn at(&self, i: usize) -> InputAt {
let c = self[i..].chars().next().into();
InputAt {
pos: i,
c: c,
byte: None,
len: c.len_utf8(),
}
}
fn next_char(&self, at: InputAt) -> Char {
at.char()
}
fn previous_char(&self, at: InputAt) -> Char {
self[..at.pos()].chars().rev().next().into()
}
fn prefix_at(&self, prefixes: &Literals, at: InputAt) -> Option<InputAt> {
prefixes
.find(&self.as_bytes()[at.pos()..])
.map(|(s, _)| self.at(at.pos() + s))
}
fn len(&self) -> usize {
self.0.len()
}
fn as_bytes(&self) -> &[u8] {
self.0.as_bytes()
}
}
#[derive(Clone, Copy, Debug)]
pub struct ByteInput<'t>(&'t str);
impl<'t> ByteInput<'t> {
pub fn new(s: &'t str) -> ByteInput<'t> {
ByteInput(s)
}
}
impl<'t> ops::Deref for ByteInput<'t> {
type Target = str;
fn deref(&self) -> &str {
self.0
}
}
impl<'t> Input for ByteInput<'t> {
#[inline(always)]
fn at(&self, i: usize) -> InputAt {
InputAt {
pos: i,
c: None.into(),
byte: self.as_bytes().get(i).map(|&b| b),
len: 1,
}
}
fn next_char(&self, at: InputAt) -> Char {
self[at.pos()..].chars().next().into()
}
fn previous_char(&self, at: InputAt) -> Char {
self[..at.pos()].chars().rev().next().into()
}
fn prefix_at(&self, prefixes: &Literals, at: InputAt) -> Option<InputAt> {
prefixes
.find(&self.as_bytes()[at.pos()..])
.map(|(s, _)| self.at(at.pos() + s))
}
fn len(&self) -> usize {
self.0.len()
}
fn as_bytes(&self) -> &[u8] {
self.0.as_bytes()
}
}