use stream::*;
use self::ParseResult::*;
use std::collections::hash_set::HashSet;
use std::cmp::Ord;
use std::fmt::{Formatter, Debug, Error};
pub trait IntoState<S, T>
{
fn into_state(self) -> ParseState<S, T>;
}
impl<S, T, R> IntoState<S, T> for R where
R: Stream<Output=S>,
S: Ord + Clone + HasNext
{
fn into_state(self) -> ParseState<S, T> {
ParseState::new(self.stream())
}
}
pub struct ParseExpectation<S>
{
expected: HashSet<&'static str>,
farthest_read: S
}
impl<S> ParseExpectation<S>
{
pub fn new(farthest_read: S, expected: Vec<&'static str>) -> ParseExpectation<S> {
ParseExpectation {
expected: expected.into_iter().collect(),
farthest_read: farthest_read
}
}
}
impl<S> ParseExpectation<S> where
S: Location + CodeSnippet
{
pub fn expected_items(&self) -> String {
let mut desc = String::new();
if self.expected.len() > 0 {
for expect in &self.expected {
desc.push('`');
desc.push_str(expect);
desc.push_str("` or ");
}
let len_without_last_or = desc.len() - 4;
desc.truncate(len_without_last_or);
}
desc
}
}
impl<S> Debug for ParseExpectation<S> where
S: Location + CodeSnippet
{
fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
let location = self.farthest_read.location();
let expected = self.expected_items();
let snippet = self.farthest_read.code_snippet(10usize);
formatter.write_fmt(
format_args!("{}: unexpected `{}`, expecting {}.", location, snippet, expected))
}
}
pub enum ParseResult<S, T>
{
Success(T),
Partial(T, ParseExpectation<S>),
Failure(ParseExpectation<S>)
}
impl<S, T> Debug for ParseResult<S, T> where
T: Debug,
S: HasNext + Location + CodeSnippet
{
fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error> {
match self {
&Success(ref data) => {
formatter.write_fmt(format_args!(
"Full match, got data `{:?}`.", data))
}
&Partial(ref data, ref expectation) => {
try!(formatter.write_fmt(format_args!(
"Partial match, got data `{:?}`. It stopped because:\n\t",
data)));
expectation.fmt(formatter)
}
&Failure(ref expectation) => {
try!(formatter.write_str("Error:\n\t"));
expectation.fmt(formatter)
}
}
}
}
pub struct ParseState<S, T>
{
pub farthest_read: S,
pub expected: Vec<&'static str>,
pub failed: bool,
pub current: S,
pub data: Option<T>
}
impl<S, T> ParseState<S, T> where
S: Ord + Clone + HasNext
{
#[inline]
pub fn new(stream: S) -> ParseState<S, T> {
ParseState {
farthest_read: stream.clone(),
expected: vec![],
failed: false,
current: stream,
data: None
}
}
pub fn is_failed(&self) -> bool {
self.failed
}
pub fn is_successful(&self) -> bool {
!self.is_failed()
}
#[inline]
pub fn error(&mut self, expect: &'static str) {
self.failed = true;
if self.current > self.farthest_read {
self.farthest_read = self.current.clone();
self.expected = vec![expect];
}
else if self.current == self.farthest_read {
self.expected.push(expect);
}
}
#[inline]
pub fn success<U>(self, data: U) -> ParseState<S, U> {
ParseState {
farthest_read: self.farthest_read,
expected: self.expected,
failed: false,
current: self.current,
data: Some(data)
}
}
pub fn failure<U>(self) -> ParseState<S, U> {
ParseState {
farthest_read: self.farthest_read,
expected: self.expected,
failed: true,
current: self.current,
data: None
}
}
pub fn mark(&self) -> S {
assert!(!self.failed, "Marking a failed ParseState is not allowed.");
self.current.clone()
}
pub fn restore_from_failure(self, mark: S) -> ParseState<S, ()> {
assert!(self.failed, "Restoring a successful ParseState is not allowed.");
self.restore(mark)
}
pub fn restore(self, mark: S) -> ParseState<S, ()> {
assert!(self.data.is_none(), "Restoring a ParseState with data is not allowed.");
ParseState {
farthest_read: self.farthest_read,
expected: self.expected,
failed: false,
current: mark,
data: None
}
}
pub fn into_result(self) -> ParseResult<S, T> {
let expectation = ParseExpectation::new(self.farthest_read, self.expected);
match self.data {
Some(data) => {
if self.current.has_next() {
Partial(data, expectation)
}
else {
Success(data)
}
}
None => {
assert!(self.failed, "Failure status must be true when extracting a failed result.");
Failure(expectation)
}
}
}
pub fn extract_data(self) -> (ParseState<S, ()>, T) {
assert!(self.is_successful() && self.data.is_some(),
"Data extraction is only possible if the state is successful and contains data.");
let data = self.data.unwrap();
let state = ParseState {
farthest_read: self.farthest_read,
expected: self.expected,
failed: self.failed,
current: self.current,
data: None
};
(state, data)
}
pub fn unwrap_data(self) -> T {
self.data.expect("data in ParseState (unwrap_data)")
}
}
impl<S> ParseState<S, ()>
{
pub fn discard_data(&mut self) {
self.data = None;
}
}
impl<S, T, I> Iterator for ParseState<S, T> where
S: Iterator<Item=I>
{
type Item = I;
fn next(&mut self) -> Option<Self::Item> {
self.current.next()
}
}
impl<S, T, P> ConsumePrefix<P> for ParseState<S, T> where
S: ConsumePrefix<P>
{
fn consume_prefix(&mut self, prefix: P) -> bool {
self.current.consume_prefix(prefix)
}
}