Struct chomp::ParseResult
[−]
[src]
#[must_use] pub struct ParseResult<'a, I: 'a, T: 'a, E: 'a>(_);
The basic return type of a parser.
This type satisfies a variant of the Monad
typeclass. Due to the limitations of Rust's
return types closures cannot be returned without boxing which has an unacceptable performance
impact.
To get around this issue and still provide a simple to use and safe (as in hard to accidentally
violate the monad laws or the assumptions taken by the parser type) an Input
wrapper is
provided which ensures that the parser state is carried properly through every call to bind
.
This is also known as a Linear Type (emulated through hiding destructors and using the
annotation #[must_use]
).
Do-notation is provided by the macro parse!
.
Equivalence with Haskell's Monad
typeclass:
f >>= g ≡ f(m).bind(g)
f >> g ≡ f(m).then(g)
return a ≡ m.ret(a)
fail a ≡ m.err(a)
It also satisfies the monad laws:
return a >>= f ≡ f a
m >>= return ≡ m
(m >>= f) >>= g ≡ m >>= (\x -> f x >>= g)
Methods
impl<'a, I, T, E> ParseResult<'a, I, T, E>
[src]
fn bind<F, U, V>(self, f: F) -> ParseResult<'a, I, U, V> where F: FnOnce(Input<'a, I>, T) -> ParseResult<'a, I, U, V>, V: From<E>
Sequentially composes the result with a parse action f
, passing any produced value as
the second parameter.
The first parameter to the supplied function f
is the parser state (Input
). This
state is then passed on to other parsers or used to return a value or an error.
Automatic conversion of E
The error value E
will automatically be converted using the From
trait to the
desired type. The downside with this using the current stable version of Rust (1.4) is that
the type inferrence will currently not use the default value for the generic V
and will
therefore require extra type hint for the error.
Examples
use chomp::parse_only; let r = parse_only(|i| { i.ret("data".to_owned()) // Explicitly state the error type .bind::<_, _, ()>(|i, x| i.ret(x + " here!")) }, b"test"); assert_eq!(r, Ok("data here!".to_owned()));
Wrapping the expression in a function will both make it easier to compose and also provides the type-hint for the error in the function signature:
use chomp::{Input, ParseResult, parse_only}; fn parser(i: Input<u8>, n: i32) -> ParseResult<u8, i32, ()> { i.ret(n + 10) } let r = parse_only(|i| i.ret(23).bind(parser), b"test"); assert_eq!(r, Ok(33));
fn then<F, U, V>(self, f: F) -> ParseResult<'a, I, U, V> where F: FnOnce(Input<'a, I>) -> ParseResult<'a, I, U, V>, V: From<E>
Sequentially composes the result with a parse action f
, discarding any produced value.
The first parameter to the supplied function f
is the parser state (Input
). This
state is then passed on to other parsers or used to return a value or an error.
Relation to bind
ParseResult::then(g) ≡ ParseResult::bind(|i, _| g(i))
Example
use chomp::{Input, U8Result, parse_only}; fn g(i: Input<u8>) -> U8Result<&'static str> { i.ret("testing!") } let r1 = parse_only(|i| i.ret("initial state").bind(|i, _| g(i)), b"data"); let r2 = parse_only(|i| i.ret("initial state").then(g), b"data"); assert_eq!(r1, Ok("testing!")); assert_eq!(r2, Ok("testing!"));
fn map<U, F>(self, f: F) -> ParseResult<'a, I, U, E> where F: FnOnce(T) -> U
Applies the function f
on the contained data if the parser is in a success state.
Example
use chomp::{parse_only, any}; let r = parse_only(|i| any(i).map(|c| c + 12), b"abc"); assert_eq!(r, Ok(b'm'));
fn map_err<V, F>(self, f: F) -> ParseResult<'a, I, T, V> where F: FnOnce(E) -> V
Applies the function f
on the contained error if the parser is in an error state.
Example
use chomp::{ParseError, parse_only}; let r = parse_only(|i| i.err::<(), _>("this is") .map_err(|e| e.to_owned() + " an error"), b"foo"); assert_eq!(r, Err(ParseError::Error(b"foo", "this is an error".to_owned())));
fn inspect<F>(self, f: F) -> ParseResult<'a, I, T, E> where F: FnOnce(&T)
Calls the function f
with a reference of the contained data if the parser is in a success
state.
Example
use chomp::{parse_only, take_while}; let r = parse_only(|i| take_while(i, |c| c != b' ').inspect(|b| { println!("{:?}", b); // Prints "test" }), b"test and more"); assert_eq!(r, Ok(&b"test"[..]));
impl<'a, I, T, E: Debug> ParseResult<'a, I, T, E>
[src]
fn unwrap(self) -> T
Unwraps a parse result, yielding the content of the success-state.
Deprecated
Use parse_only
or buffer::Stream
implementations to obtain a Result
instead of acting
on the ParseResult
directly.
Panics
Panics if the parse result is in an error-state or if the parsing is incomplete. Will provide a panic message based on the value of the error.
Examples
use chomp::{Input, token}; let r = token(Input::new(b"a"), b'a'); assert_eq!(r.unwrap(), b'a');
use chomp::{Input, token}; let r = token(Input::new(b"a"), b'b'); // Panics with "called `ParseResult::unwrap` on an error: Expected (98)" assert_eq!(r.unwrap(), b'a');
use chomp::{Input, take}; let r = take(Input::new(b"a"), 2); // Panics with "called `ParseResult::unwrap` on an incomplete state (requested 1 tokens)" assert_eq!(r.unwrap(), b"a");
fn expect(self, msg: &str) -> T
Unwraps a parse result, yielding the contents of the success state.
Deprecated
Use parse_only
or buffer::Stream
implementations to obtain a Result
instead of acting
on the ParseResult
directly.
Panics
Panics if the parse result is in an error-state or if the parsing is incomplete. Will provide a panic message based on the supplied message and the value of the error.
Examples
use chomp::{Input, token}; let r = token(Input::new(b"a"), b'b'); // Panics with "Wanted character b: Expected(98)" assert_eq!(r.expect("Wanted character b"), b'a');
impl<'a, I, T: Debug, E> ParseResult<'a, I, T, E>
[src]
fn unwrap_err(self) -> E
Unwraps a parse result, yielding the contents of the error state.
Deprecated
Use parse_only
or buffer::Stream
implementations to obtain a Result
instead of acting
on the ParseResult
directly.
Panics
Panics if the parse result is in a success-state or if the parsing is incomplete. Will provide a panic message based on the value of the success or incomplete state.
Examples
use chomp::{Error, Input, token}; let r = token(Input::new(b"a"), b'b'); assert_eq!(r.unwrap_err(), Error::Expected(98));
use chomp::{Error, Input, token}; let r = token(Input::new(b"a"), b'a'); // Panics with "called `ParseResult::unwrap_err` on a success state: 97" assert_eq!(r.unwrap_err(), Error::Expected(98));
Trait Implementations
impl<'a, I: Hash + 'a, T: Hash + 'a, E: Hash + 'a> Hash for ParseResult<'a, I, T, E>
[src]
fn hash<__HITE: Hasher>(&self, __arg_0: &mut __HITE)
Feeds this value into the state given, updating the hasher as necessary.
fn hash_slice<H>(data: &[Self], state: &mut H) where H: Hasher
1.3.0
Feeds a slice of this type into the state provided.
impl<'a, I: PartialOrd + 'a, T: PartialOrd + 'a, E: PartialOrd + 'a> PartialOrd for ParseResult<'a, I, T, E>
[src]
fn partial_cmp(&self, __arg_0: &ParseResult<'a, I, T, E>) -> Option<Ordering>
This method returns an ordering between self
and other
values if one exists. Read more
fn lt(&self, __arg_0: &ParseResult<'a, I, T, E>) -> bool
This method tests less than (for self
and other
) and is used by the <
operator. Read more
fn le(&self, __arg_0: &ParseResult<'a, I, T, E>) -> bool
This method tests less than or equal to (for self
and other
) and is used by the <=
operator. Read more
fn gt(&self, __arg_0: &ParseResult<'a, I, T, E>) -> bool
This method tests greater than (for self
and other
) and is used by the >
operator. Read more
fn ge(&self, __arg_0: &ParseResult<'a, I, T, E>) -> bool
This method tests greater than or equal to (for self
and other
) and is used by the >=
operator. Read more
impl<'a, I: Ord + 'a, T: Ord + 'a, E: Ord + 'a> Ord for ParseResult<'a, I, T, E>
[src]
fn cmp(&self, __arg_0: &ParseResult<'a, I, T, E>) -> Ordering
This method returns an Ordering
between self
and other
. Read more
impl<'a, I: PartialEq + 'a, T: PartialEq + 'a, E: PartialEq + 'a> PartialEq for ParseResult<'a, I, T, E>
[src]
fn eq(&self, __arg_0: &ParseResult<'a, I, T, E>) -> bool
This method tests for self
and other
values to be equal, and is used by ==
. Read more
fn ne(&self, __arg_0: &ParseResult<'a, I, T, E>) -> bool
This method tests for !=
.
impl<'a, I: Eq + 'a, T: Eq + 'a, E: Eq + 'a> Eq for ParseResult<'a, I, T, E>
[src]
impl<'a, I: Debug + 'a, T: Debug + 'a, E: Debug + 'a> Debug for ParseResult<'a, I, T, E>
[src]
impl<'a, I, T, E> IntoInner for ParseResult<'a, I, T, E>
[src]
Primitive: Consumes the ParseResult
and exposes the internal state.
Primitive
Only used by fundamental parsers and combinators.
Motivation
The ParseResult
type is a semi-linear type, supposed to act like a linear type while used in
a parsing context to carry the state. Normally it should be as restrictive as the Input
type
in terms of how much it exposes its internals, but to make it easier to use the parsers
unwrap
, unwrap_err
and expect
were introduced which breaks the linearity guarantee when
used early.
The IntoInner
trait implementation allows fundamental parsers and combinators to expose the
inner State
of the ParseResult
and act on this.
Example
use chomp::{Input, ParseResult, parse_only, take}; use chomp::primitives::{InputClone, IntoInner, State}; // Version of option() which also catches incomplete fn my_combinator<'a, I, T, E, F>(i: Input<'a, I>, f: F, default: T) -> ParseResult<'a, I, T, E> where F: FnOnce(Input<'a, I>) -> ParseResult<'a, I, T, E> { match f(i.clone()).into_inner() { // Data, preserve the buffer and return State::Data(b, d) => b.ret(d), // Not data, use original buffer and return default _ => i.ret(default), } } let r = parse_only(|i| my_combinator(i, |i| take(i, 10), &b"test"[..]), b"foo"); assert_eq!(r, Ok(&b"test"[..]));
type Inner = State<'a, I, T, E>
The inner type to be revealed.
fn into_inner(self) -> Self::Inner
Primitive: Consumes self and reveals the inner state. Read more