Struct chomp::types::ParseResult
[−]
[src]
#[must_use]pub struct ParseResult<I: Input, T, E>(_, _);
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<I: Input, T, E> ParseResult<I, T, E>
[src]
fn bind<F, U, V>(self, f: F) -> ParseResult<I, U, V> where
F: FnOnce(I, T) -> ParseResult<I, U, V>,
V: From<E>,
F: FnOnce(I, T) -> ParseResult<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::prelude::{Input, 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::prelude::{Input, ParseResult, parse_only}; fn parser<I: Input>(i: I, n: i32) -> ParseResult<I, 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<I, U, V> where
F: FnOnce(I) -> ParseResult<I, U, V>,
V: From<E>,
F: FnOnce(I) -> ParseResult<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::prelude::{Input, SimpleResult, parse_only}; fn g<I: Input>(i: I) -> SimpleResult<I, &'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<I, U, E> where
F: FnOnce(T) -> U,
F: FnOnce(T) -> U,
Applies the function f
on the contained data if the parser is in a success state.
Example
use chomp::prelude::{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<I, T, V> where
F: FnOnce(E) -> V,
F: FnOnce(E) -> V,
Applies the function f
on the contained error if the parser is in an error state.
Example
use chomp::prelude::{Input, 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((&b"foo"[..], "this is an error".to_owned())));
fn inspect<F>(self, f: F) -> ParseResult<I, T, E> where
F: FnOnce(&T),
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::prelude::{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"[..]));
Trait Implementations
impl<I: Debug + Input, T: Debug, E: Debug> Debug for ParseResult<I, T, E>
[src]
impl<I: Eq + Input, T: Eq, E: Eq> Eq for ParseResult<I, T, E>
[src]
impl<I: PartialEq + Input, T: PartialEq, E: PartialEq> PartialEq for ParseResult<I, T, E>
[src]
fn eq(&self, __arg_0: &ParseResult<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<I, T, E>) -> bool
This method tests for !=
.
impl<I: Ord + Input, T: Ord, E: Ord> Ord for ParseResult<I, T, E>
[src]
fn cmp(&self, __arg_0: &ParseResult<I, T, E>) -> Ordering
This method returns an Ordering
between self
and other
. Read more
impl<I: PartialOrd + Input, T: PartialOrd, E: PartialOrd> PartialOrd for ParseResult<I, T, E>
[src]
fn partial_cmp(&self, __arg_0: &ParseResult<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<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<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<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<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<I: Hash + Input, T: Hash, E: Hash> Hash for ParseResult<I, T, E>
[src]
fn hash<__HITE: Hasher>(&self, __arg_0: &mut __HITE)
Feeds this value into the given [Hasher
]. Read more
fn hash_slice<H>(data: &[Self], state: &mut H) where
H: Hasher,
1.3.0
H: Hasher,
Feeds a slice of this type into the given [Hasher
]. Read more
impl<I: Input, T, E> IntoInner for ParseResult<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 the IntoInner
trait implementation
allows fundamental parsers and combinators to expose the inner Result
of the ParseResult
and act on this.