mirror of
https://github.com/zaphar/abortable_parser.git
synced 2025-07-22 20:39:50 -04:00
FEATURE: Pass our input around as context for errors and incompletes.
This commit is contained in:
parent
de0c03398c
commit
5cb8effcca
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "abortable_parser"
|
name = "abortable_parser"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
authors = ["Jeremy Wall <jeremy@marzhillstudios.com>"]
|
authors = ["Jeremy Wall <jeremy@marzhillstudios.com>"]
|
||||||
description = "A parser combinator library with an emphasis on error handling"
|
description = "A parser combinator library with an emphasis on error handling"
|
||||||
repository = "https://github.com/zaphar/abortable_parser"
|
repository = "https://github.com/zaphar/abortable_parser"
|
||||||
|
@ -28,11 +28,11 @@ where
|
|||||||
{
|
{
|
||||||
match result {
|
match result {
|
||||||
Result::Complete(i, _) => Result::Fail(Error::new(
|
Result::Complete(i, _) => Result::Fail(Error::new(
|
||||||
"Matched on input when we shouldn't have.".to_string(),
|
"Matched on input when we shouldn't have.",
|
||||||
&i,
|
Box::new(i.clone()),
|
||||||
)),
|
)),
|
||||||
Result::Abort(e) => Result::Abort(e),
|
Result::Abort(e) => Result::Abort(e),
|
||||||
Result::Incomplete(offset) => Result::Incomplete(offset),
|
Result::Incomplete(ctx) => Result::Incomplete(ctx),
|
||||||
Result::Fail(_) => Result::Complete(i, ()),
|
Result::Fail(_) => Result::Complete(i, ()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,7 +95,7 @@ macro_rules! peek {
|
|||||||
let _i = $i.clone();
|
let _i = $i.clone();
|
||||||
match $f!(_i, $($args)*) {
|
match $f!(_i, $($args)*) {
|
||||||
Result::Complete(_, o) => Result::Complete($i, o),
|
Result::Complete(_, o) => Result::Complete($i, o),
|
||||||
Result::Incomplete(offset) => Result::Incomplete(offset),
|
Result::Incomplete(ctx) => Result::Incomplete(ctx),
|
||||||
Result::Abort(e) => Result::Abort(e),
|
Result::Abort(e) => Result::Abort(e),
|
||||||
Result::Fail(e) => Result::Fail(e),
|
Result::Fail(e) => Result::Fail(e),
|
||||||
}
|
}
|
||||||
@ -129,7 +129,7 @@ where
|
|||||||
{
|
{
|
||||||
match result {
|
match result {
|
||||||
Result::Complete(i, o) => Result::Complete(i, o),
|
Result::Complete(i, o) => Result::Complete(i, o),
|
||||||
Result::Incomplete(offset) => Result::Incomplete(offset),
|
Result::Incomplete(ctx) => Result::Incomplete(ctx),
|
||||||
Result::Fail(e) => Result::Abort(e),
|
Result::Fail(e) => Result::Abort(e),
|
||||||
Result::Abort(e) => Result::Abort(e),
|
Result::Abort(e) => Result::Abort(e),
|
||||||
}
|
}
|
||||||
@ -174,9 +174,9 @@ macro_rules! wrap_err {
|
|||||||
let _i = $i.clone();
|
let _i = $i.clone();
|
||||||
match $f!($i, $($args)*) {
|
match $f!($i, $($args)*) {
|
||||||
$crate::Result::Complete(i, o) => $crate::Result::Complete(i, o),
|
$crate::Result::Complete(i, o) => $crate::Result::Complete(i, o),
|
||||||
$crate::Result::Incomplete(offset) => $crate::Result::Incomplete(offset),
|
$crate::Result::Incomplete(ctx) => $crate::Result::Incomplete(ctx),
|
||||||
$crate::Result::Fail(e) => $crate::Result::Fail($crate::Error::caused_by($e, &_i, Box::new(e))),
|
$crate::Result::Fail(e) => $crate::Result::Fail($crate::Error::caused_by($e, Box::new(e), Box::new(_i.clone()))),
|
||||||
$crate::Result::Abort(e) => $crate::Result::Abort($crate::Error::caused_by($e, &_i, Box::new(e))),
|
$crate::Result::Abort(e) => $crate::Result::Abort($crate::Error::caused_by($e, Box::new(e), Box::new(_i.clone()))),
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
||||||
@ -200,7 +200,7 @@ where
|
|||||||
{
|
{
|
||||||
match result {
|
match result {
|
||||||
Result::Complete(i, o) => Result::Complete(i, o),
|
Result::Complete(i, o) => Result::Complete(i, o),
|
||||||
Result::Incomplete(offset) => Result::Incomplete(offset),
|
Result::Incomplete(ctx) => Result::Incomplete(ctx),
|
||||||
Result::Fail(e) => Result::Fail(e),
|
Result::Fail(e) => Result::Fail(e),
|
||||||
Result::Abort(e) => Result::Fail(e),
|
Result::Abort(e) => Result::Fail(e),
|
||||||
}
|
}
|
||||||
@ -242,7 +242,7 @@ where
|
|||||||
{
|
{
|
||||||
match result {
|
match result {
|
||||||
Result::Complete(i, o) => Result::Complete(i, o),
|
Result::Complete(i, o) => Result::Complete(i, o),
|
||||||
Result::Incomplete(ref offset) => Result::Abort(Error::new(msg, offset)),
|
Result::Incomplete(ctx) => Result::Abort(Error::new(msg, Box::new(ctx))),
|
||||||
Result::Fail(e) => Result::Abort(e),
|
Result::Fail(e) => Result::Abort(e),
|
||||||
Result::Abort(e) => Result::Abort(e),
|
Result::Abort(e) => Result::Abort(e),
|
||||||
}
|
}
|
||||||
@ -255,7 +255,7 @@ where
|
|||||||
S: Into<String>,
|
S: Into<String>,
|
||||||
{
|
{
|
||||||
match result {
|
match result {
|
||||||
Result::Incomplete(offset) => Result::Fail(Error::new(msg.into(), &offset)),
|
Result::Incomplete(ctx) => Result::Fail(Error::new(msg.into(), Box::new(ctx))),
|
||||||
Result::Complete(i, o) => Result::Complete(i, o),
|
Result::Complete(i, o) => Result::Complete(i, o),
|
||||||
Result::Fail(e) => Result::Fail(e),
|
Result::Fail(e) => Result::Fail(e),
|
||||||
Result::Abort(e) => Result::Abort(e),
|
Result::Abort(e) => Result::Abort(e),
|
||||||
@ -291,7 +291,7 @@ macro_rules! complete {
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! must_complete {
|
macro_rules! must_complete {
|
||||||
($i:expr, $e:expr, $f:ident!( $( $args:tt )* ) ) => {{
|
($i:expr, $e:expr, $f:ident!( $( $args:tt )* ) ) => {{
|
||||||
$crate::combinators::must_complete($f!($i, $($args)*), $e)
|
$crate::combinators::must_complete($f!($i.clone(), $($args)*), $e)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
($i:expr, $efn:expr, $f:ident) => {
|
($i:expr, $efn:expr, $f:ident) => {
|
||||||
@ -362,8 +362,8 @@ macro_rules! do_each {
|
|||||||
let $val = o;
|
let $val = o;
|
||||||
do_each!(i, $($rest)*)
|
do_each!(i, $($rest)*)
|
||||||
}
|
}
|
||||||
$crate::Result::Incomplete(offset) => {
|
$crate::Result::Incomplete(ctx) => {
|
||||||
Result::Incomplete(offset)
|
Result::Incomplete(ctx)
|
||||||
}
|
}
|
||||||
$crate::Result::Fail(e) => Result::Fail(e),
|
$crate::Result::Fail(e) => Result::Fail(e),
|
||||||
$crate::Result::Abort(e) => Result::Abort(e),
|
$crate::Result::Abort(e) => Result::Abort(e),
|
||||||
@ -376,8 +376,8 @@ macro_rules! do_each {
|
|||||||
$crate::Result::Complete(i, _) => {
|
$crate::Result::Complete(i, _) => {
|
||||||
do_each!(i, $($rest)*)
|
do_each!(i, $($rest)*)
|
||||||
}
|
}
|
||||||
$crate::Result::Incomplete(offset) => {
|
$crate::Result::Incomplete(ctx) => {
|
||||||
Result::Incomplete(offset)
|
Result::Incomplete(ctx)
|
||||||
}
|
}
|
||||||
$crate::Result::Fail(e) => Result::Fail(e),
|
$crate::Result::Fail(e) => Result::Fail(e),
|
||||||
$crate::Result::Abort(e) => Result::Abort(e),
|
$crate::Result::Abort(e) => Result::Abort(e),
|
||||||
@ -462,8 +462,8 @@ macro_rules! either {
|
|||||||
Result::Complete(i, o)
|
Result::Complete(i, o)
|
||||||
}
|
}
|
||||||
// Incompletes may still be parseable.
|
// Incompletes may still be parseable.
|
||||||
$crate::Result::Incomplete(i) => {
|
$crate::Result::Incomplete(ctx) => {
|
||||||
Result::Incomplete(i)
|
Result::Incomplete(ctx)
|
||||||
}
|
}
|
||||||
// Fail means it didn't match so we are now done.
|
// Fail means it didn't match so we are now done.
|
||||||
$crate::Result::Fail(e) => {
|
$crate::Result::Fail(e) => {
|
||||||
@ -483,8 +483,8 @@ macro_rules! either {
|
|||||||
Result::Complete(i, o)
|
Result::Complete(i, o)
|
||||||
}
|
}
|
||||||
// Incompletes may still be parseable.
|
// Incompletes may still be parseable.
|
||||||
$crate::Result::Incomplete(i) => {
|
$crate::Result::Incomplete(ctx) => {
|
||||||
Result::Incomplete(i)
|
Result::Incomplete(ctx)
|
||||||
}
|
}
|
||||||
// Fail means it didn't match so continue to next one.
|
// Fail means it didn't match so continue to next one.
|
||||||
$crate::Result::Fail(_) => {
|
$crate::Result::Fail(_) => {
|
||||||
@ -516,7 +516,7 @@ where
|
|||||||
match result {
|
match result {
|
||||||
Result::Complete(i, o) => Result::Complete(i, Some(o)),
|
Result::Complete(i, o) => Result::Complete(i, Some(o)),
|
||||||
// Incomplete could still work possibly parse.
|
// Incomplete could still work possibly parse.
|
||||||
Result::Incomplete(i) => Result::Incomplete(i),
|
Result::Incomplete(ctx) => Result::Incomplete(ctx),
|
||||||
// Fail just means it didn't match.
|
// Fail just means it didn't match.
|
||||||
Result::Fail(_) => Result::Complete(iter, None),
|
Result::Fail(_) => Result::Complete(iter, None),
|
||||||
// Aborts are hard failures that the parser can't recover from.
|
// Aborts are hard failures that the parser can't recover from.
|
||||||
@ -644,7 +644,7 @@ macro_rules! separated {
|
|||||||
// We require at least one item for our list
|
// We require at least one item for our list
|
||||||
let head = $item_rule!($i.clone(), $($item_args)*);
|
let head = $item_rule!($i.clone(), $($item_args)*);
|
||||||
match head {
|
match head {
|
||||||
Result::Incomplete(offset) => Result::Incomplete(offset),
|
Result::Incomplete(ctx) => Result::Incomplete(ctx),
|
||||||
Result::Fail(e) => Result::Fail(e),
|
Result::Fail(e) => Result::Fail(e),
|
||||||
Result::Abort(e) => Result::Abort(e),
|
Result::Abort(e) => Result::Abort(e),
|
||||||
Result::Complete(i,item) => {
|
Result::Complete(i,item) => {
|
||||||
@ -659,7 +659,7 @@ macro_rules! separated {
|
|||||||
);
|
);
|
||||||
match tail_result {
|
match tail_result {
|
||||||
Result::Fail(e) => Result::Fail(e),
|
Result::Fail(e) => Result::Fail(e),
|
||||||
Result::Incomplete(offset) => Result::Incomplete(offset),
|
Result::Incomplete(ctx) => Result::Incomplete(ctx),
|
||||||
Result::Abort(e) => Result::Abort(e),
|
Result::Abort(e) => Result::Abort(e),
|
||||||
Result::Complete(i, mut tail) => {
|
Result::Complete(i, mut tail) => {
|
||||||
list.extend(tail.drain(0..));
|
list.extend(tail.drain(0..));
|
||||||
@ -721,7 +721,7 @@ macro_rules! text_token {
|
|||||||
} else {
|
} else {
|
||||||
Result::Fail(Error::new(
|
Result::Fail(Error::new(
|
||||||
format!("Expected {} but didn't get it.", $e),
|
format!("Expected {} but didn't get it.", $e),
|
||||||
&$i,
|
Box::new($i.clone()),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
@ -759,13 +759,13 @@ macro_rules! until {
|
|||||||
return Result::Complete(_i, $i.span(range));
|
return Result::Complete(_i, $i.span(range));
|
||||||
},
|
},
|
||||||
Result::Abort(e) => return Result::Abort(e),
|
Result::Abort(e) => return Result::Abort(e),
|
||||||
Result::Incomplete(offset) => return Result::Incomplete(offset),
|
Result::Incomplete(ctx) => return Result::Incomplete(ctx),
|
||||||
Result::Fail(_) => {
|
Result::Fail(_) => {
|
||||||
// noop
|
// noop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let None = _i.next() {
|
if let None = _i.next() {
|
||||||
return Result::Incomplete(_i.get_offset());
|
return Result::Incomplete(_i.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -789,7 +789,7 @@ macro_rules! discard {
|
|||||||
use $crate::Result;
|
use $crate::Result;
|
||||||
match $rule!($i, $($args)*) {
|
match $rule!($i, $($args)*) {
|
||||||
Result::Complete(i, _) => Result::Complete(i, ()),
|
Result::Complete(i, _) => Result::Complete(i, ()),
|
||||||
Result::Incomplete(offset) => Result::Incomplete(offset),
|
Result::Incomplete(ctx) => Result::Incomplete(ctx),
|
||||||
Result::Fail(e) => Result::Fail(e),
|
Result::Fail(e) => Result::Fail(e),
|
||||||
Result::Abort(e) => Result::Abort(e),
|
Result::Abort(e) => Result::Abort(e),
|
||||||
}
|
}
|
||||||
@ -803,10 +803,10 @@ pub fn ascii_ws<'a, I: InputIter<Item = &'a u8>>(mut i: I) -> Result<I, u8> {
|
|||||||
if (*b as char).is_whitespace() {
|
if (*b as char).is_whitespace() {
|
||||||
Result::Complete(i, *b)
|
Result::Complete(i, *b)
|
||||||
} else {
|
} else {
|
||||||
Result::Fail(Error::new("Not whitespace".to_string(), &i))
|
Result::Fail(Error::new("Not whitespace".to_string(), Box::new(i.clone())))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => Result::Fail(Error::new("Unexpected End Of Input".to_string(), &i)),
|
None => Result::Fail(Error::new("Unexpected End Of Input".to_string(), Box::new(i.clone()))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -815,7 +815,7 @@ pub fn ascii_ws<'a, I: InputIter<Item = &'a u8>>(mut i: I) -> Result<I, u8> {
|
|||||||
pub fn eoi<I: InputIter>(i: I) -> Result<I, ()> {
|
pub fn eoi<I: InputIter>(i: I) -> Result<I, ()> {
|
||||||
let mut _i = i.clone();
|
let mut _i = i.clone();
|
||||||
match _i.next() {
|
match _i.next() {
|
||||||
Some(_) => Result::Fail(Error::new("Expected End Of Input".to_string(), &i)),
|
Some(_) => Result::Fail(Error::new("Expected End Of Input".to_string(), Box::new(i.clone()))),
|
||||||
None => Result::Complete(i, ()),
|
None => Result::Complete(i, ()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -911,14 +911,14 @@ macro_rules! consume_all {
|
|||||||
// noop
|
// noop
|
||||||
},
|
},
|
||||||
Result::Abort(e) => return Result::Abort(e),
|
Result::Abort(e) => return Result::Abort(e),
|
||||||
Result::Incomplete(offset) => return Result::Incomplete(offset),
|
Result::Incomplete(ctx) => return Result::Incomplete(ctx),
|
||||||
Result::Fail(_) => {
|
Result::Fail(_) => {
|
||||||
let range = SpanRange::Range(start_offset.._i.get_offset());
|
let range = SpanRange::Range(start_offset.._i.get_offset());
|
||||||
return Result::Complete(_i, $i.span(range));
|
return Result::Complete(_i, $i.span(range));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let None = _i.next() {
|
if let None = _i.next() {
|
||||||
return Result::Incomplete(_i.get_offset());
|
return Result::Incomplete(_i.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -939,10 +939,10 @@ pub fn ascii_alphanumeric<'a, I: InputIter<Item=&'a u8>>(mut i: I) -> Result<I,
|
|||||||
if c.is_ascii_alphabetic() || c.is_ascii_digit() {
|
if c.is_ascii_alphabetic() || c.is_ascii_digit() {
|
||||||
Result::Complete(i, *b)
|
Result::Complete(i, *b)
|
||||||
} else {
|
} else {
|
||||||
Result::Fail(Error::new("Not an alphanumeric character".to_string(), &i))
|
Result::Fail(Error::new("Not an alphanumeric character".to_string(), Box::new(i.clone())))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => Result::Fail(Error::new("Unexpected End Of Input.".to_string(), &i)),
|
None => Result::Fail(Error::new("Unexpected End Of Input.".to_string(), Box::new(i.clone()))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -954,10 +954,10 @@ pub fn ascii_digit<'a, I: InputIter<Item = &'a u8>>(mut i: I) -> Result<I, u8> {
|
|||||||
if (*b as char).is_ascii_digit() {
|
if (*b as char).is_ascii_digit() {
|
||||||
Result::Complete(i, *b)
|
Result::Complete(i, *b)
|
||||||
} else {
|
} else {
|
||||||
Result::Fail(Error::new("Not an digit character".to_string(), &i))
|
Result::Fail(Error::new("Not an digit character".to_string(), Box::new(i.clone())))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => Result::Fail(Error::new("Unexpected End Of Input.".to_string(), &i)),
|
None => Result::Fail(Error::new("Unexpected End Of Input.".to_string(), Box::new(i.clone()))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -969,10 +969,10 @@ pub fn ascii_alpha<'a, I: InputIter<Item = &'a u8>>(mut i: I) -> Result<I, u8> {
|
|||||||
if (*b as char).is_ascii_alphabetic() {
|
if (*b as char).is_ascii_alphabetic() {
|
||||||
Result::Complete(i, *b)
|
Result::Complete(i, *b)
|
||||||
} else {
|
} else {
|
||||||
Result::Fail(Error::new("Not an alpha character".to_string(), &i))
|
Result::Fail(Error::new("Not an alpha character".to_string(), Box::new(i.clone())))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => Result::Fail(Error::new("Unexpected End Of Input.".to_string(), &i)),
|
None => Result::Fail(Error::new("Unexpected End Of Input.".to_string(), Box::new(i.clone()))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
47
src/lib.rs
47
src/lib.rs
@ -102,7 +102,7 @@
|
|||||||
//! assert!(bad_result.is_abort());
|
//! assert!(bad_result.is_abort());
|
||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
use std::fmt::Display;
|
use std::fmt::{Display,Debug};
|
||||||
use std::iter::Iterator;
|
use std::iter::Iterator;
|
||||||
use std::result;
|
use std::result;
|
||||||
|
|
||||||
@ -150,36 +150,34 @@ pub trait InputIter: Iterator + Clone + Offsetable {}
|
|||||||
/// The custom error type for use in `Result::{Fail, Abort}`.
|
/// The custom error type for use in `Result::{Fail, Abort}`.
|
||||||
/// Stores a wrapped err that must implement Display as well as an offset and
|
/// Stores a wrapped err that must implement Display as well as an offset and
|
||||||
/// an optional cause.
|
/// an optional cause.
|
||||||
#[derive(Debug)]
|
#[derive(Debug,Clone)]
|
||||||
pub struct Error
|
pub struct Error<C>
|
||||||
|
where
|
||||||
|
C: InputIter,
|
||||||
{
|
{
|
||||||
msg: String,
|
msg: String,
|
||||||
offset: usize,
|
cause: Option<Box<Error<C>>>,
|
||||||
cause: Option<Box<Error>>,
|
context: Box<C>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error {
|
impl<C: InputIter> Error<C> {
|
||||||
/// Constructs a new Error with an offset and no cause.
|
/// Constructs a new Error with an offset and no cause.
|
||||||
pub fn new<S, D: Into<String>>(msg: D, offset: &S) -> Self
|
pub fn new<D: Into<String>>(msg: D, ctx: Box<C>) -> Self
|
||||||
where
|
|
||||||
S: Offsetable,
|
|
||||||
{
|
{
|
||||||
Error {
|
Error {
|
||||||
msg: msg.into(),
|
msg: msg.into(),
|
||||||
offset: offset.get_offset(),
|
|
||||||
cause: None,
|
cause: None,
|
||||||
|
context: ctx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a new Error with an offset and a cause.
|
/// Constructs a new Error with an offset and a cause.
|
||||||
pub fn caused_by<'a, S, D: Into<String>>(msg: D, offset: &'a S, cause: Box<Self>) -> Self
|
pub fn caused_by<'a, D: Into<String>>(msg: D, cause: Box<Self>, ctx: Box<C>) -> Self
|
||||||
where
|
|
||||||
S: Offsetable,
|
|
||||||
{
|
{
|
||||||
Error {
|
Error {
|
||||||
msg: msg.into(),
|
msg: msg.into(),
|
||||||
offset: offset.get_offset(),
|
|
||||||
cause: Some(cause),
|
cause: Some(cause),
|
||||||
|
context: ctx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +187,7 @@ impl Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `Some(cause)` if there is one, None otherwise.
|
/// Returns `Some(cause)` if there is one, None otherwise.
|
||||||
pub fn get_cause<'a>(&'a self) -> Option<&'a Error> {
|
pub fn get_cause<'a>(&'a self) -> Option<&'a Error<C>> {
|
||||||
match self.cause {
|
match self.cause {
|
||||||
Some(ref e) => Some(e),
|
Some(ref e) => Some(e),
|
||||||
None => None
|
None => None
|
||||||
@ -198,11 +196,18 @@ impl Error {
|
|||||||
|
|
||||||
// Returns the offset at which this Error happened.
|
// Returns the offset at which this Error happened.
|
||||||
pub fn get_offset(&self) -> usize {
|
pub fn get_offset(&self) -> usize {
|
||||||
self.offset
|
self.context.get_offset()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_context(&self) -> &C
|
||||||
|
where
|
||||||
|
C: InputIter,
|
||||||
|
{
|
||||||
|
self.context.as_ref()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Error {
|
impl<C: InputIter> Display for Error<C> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> result::Result<(), std::fmt::Error> {
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> result::Result<(), std::fmt::Error> {
|
||||||
try!(write!(f, "{}", self.msg));
|
try!(write!(f, "{}", self.msg));
|
||||||
match self.cause {
|
match self.cause {
|
||||||
@ -212,7 +217,7 @@ impl Display for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::error::Error for Error {}
|
impl<C: InputIter + Debug> std::error::Error for Error<C> {}
|
||||||
|
|
||||||
/// The result of a parsing attempt.
|
/// The result of a parsing attempt.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -222,11 +227,11 @@ pub enum Result<I: InputIter, O>
|
|||||||
Complete(I, O),
|
Complete(I, O),
|
||||||
/// Incomplete indicates input ended before a match could be completed.
|
/// Incomplete indicates input ended before a match could be completed.
|
||||||
/// It contains the offset at which the input ended before a match could be completed.
|
/// It contains the offset at which the input ended before a match could be completed.
|
||||||
Incomplete(usize),
|
Incomplete(I),
|
||||||
/// Fail represents a failed match.
|
/// Fail represents a failed match.
|
||||||
Fail(Error),
|
Fail(Error<I>),
|
||||||
/// Abort represents a match failure that the parser cannot recover from.
|
/// Abort represents a match failure that the parser cannot recover from.
|
||||||
Abort(Error),
|
Abort(Error<I>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: InputIter, O> Result<I, O>
|
impl<I: InputIter, O> Result<I, O>
|
||||||
|
10
src/test.rs
10
src/test.rs
@ -53,7 +53,7 @@ where
|
|||||||
I: InputIter<Item = C>,
|
I: InputIter<Item = C>,
|
||||||
C: Debug + Display,
|
C: Debug + Display,
|
||||||
{
|
{
|
||||||
Result::Fail(super::Error::new("AAAAHHH!!!".to_string(), &i))
|
Result::Fail(super::Error::new("AAAAHHH!!!".to_string(), Box::new(i.clone())))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_byte<'a, I>(mut i: I) -> Result<I, u8>
|
fn parse_byte<'a, I>(mut i: I) -> Result<I, u8>
|
||||||
@ -62,15 +62,15 @@ where
|
|||||||
{
|
{
|
||||||
match i.next() {
|
match i.next() {
|
||||||
Some(b) => Result::Complete(i, *b),
|
Some(b) => Result::Complete(i, *b),
|
||||||
None => Result::Incomplete(i.get_offset()),
|
None => Result::Incomplete(i.clone()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn will_not_complete<'a, I>(_: I) -> Result<I, String>
|
fn will_not_complete<'a, I>(i: I) -> Result<I, String>
|
||||||
where
|
where
|
||||||
I: InputIter<Item = &'a u8>,
|
I: InputIter<Item = &'a u8>,
|
||||||
{
|
{
|
||||||
Result::Incomplete(0)
|
Result::Incomplete(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_three<'a, I>(i: I) -> Result<I, String>
|
fn parse_three<'a, I>(i: I) -> Result<I, String>
|
||||||
@ -90,7 +90,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if out.len() != 3 {
|
if out.len() != 3 {
|
||||||
Result::Incomplete(_i.get_offset())
|
Result::Incomplete(_i)
|
||||||
} else {
|
} else {
|
||||||
Result::Complete(_i, out)
|
Result::Complete(_i, out)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user