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 = E>(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 = E>(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]

fn fmt(&self, __arg_0: &mut Formatter) -> Result

Formats the value using the given formatter.

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>

fn into_inner(self) -> Self::Inner

Primitive: Consumes self and reveals the inner state. Read more