Struct ParserState

struct ParserState<'i, R: RuleType> { ... }

The complete state of a Parser.

Implementations

impl<'i, R: RuleType> ParserState<'i, R>

fn new(input: &'i str) -> Box<Self>

Allocates a fresh ParserState object to the heap and returns the owned Box. This Box will be passed from closure to closure based on the needs of the specified Parser.

Examples

# use pest;
let input = "";
let state: Box<pest::ParserState<&str>> = pest::ParserState::new(input);
fn get_parse_attempts(self: &Self) -> &ParseAttempts<R>

Get all parse attempts after process of parsing is finished.

fn position(self: &Self) -> &Position<'i>

Returns a reference to the current Position of the ParserState.

Examples

# use pest;
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {
    ab
}

let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let position = state.position();
assert_eq!(position.pos(), 0);
fn atomicity(self: &Self) -> Atomicity

Returns the current atomicity of the ParserState.

Examples

# use pest;
# use pest::Atomicity;
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {
    ab
}

let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let atomicity = state.atomicity();
assert_eq!(atomicity, Atomicity::NonAtomic);
fn rule<F>(self: Box<Self>, rule: R, f: F) -> ParseResult<Box<Self>>
where
    F: FnOnce(Box<Self>) -> ParseResult<Box<Self>>

Wrapper needed to generate tokens. This will associate the R type rule to the closure meant to match the rule.

Examples

# use pest;
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {
    a
}

let input = "a";
let pairs: Vec<_> = pest::state(input, |state| {
    state.rule(Rule::a, |s| Ok(s))
}).unwrap().collect();

assert_eq!(pairs.len(), 1);
fn tag_node(self: Box<Self>, tag: &'i str) -> ParseResult<Box<Self>>

Tag current node

Examples

Try to recognize the one specified in a set of characters

use pest::{state, ParseResult, ParserState, iterators::Pair};
#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {
    character,
}
fn mark_c(state: Box<ParserState<Rule>>) -> ParseResult<Box<ParserState<Rule>>> {
    state.sequence(|state| {
        character(state)
            .and_then(|state| character(state))
            .and_then(|state| character(state))
            .and_then(|state| state.tag_node("c"))
            .and_then(|state| character(state))
    })
}
fn character(state: Box<ParserState<Rule>>) -> ParseResult<Box<ParserState<Rule>>> {
    state.rule(Rule::character, |state| state.match_range('a'..'z'))
}

let input = "abcd";
let pairs = state(input, mark_c).unwrap();
// find all node tag as `c`
let find: Vec<Pair<Rule>> = pairs.filter(|s| s.as_node_tag() == Some("c")).collect();
assert_eq!(find[0].as_str(), "c")
fn sequence<F>(self: Box<Self>, f: F) -> ParseResult<Box<Self>>
where
    F: FnOnce(Box<Self>) -> ParseResult<Box<Self>>

Starts a sequence of transformations provided by f from the Box<ParserState>. Returns the same Result returned by f in the case of an Ok, or Err with the current Box<ParserState> otherwise.

This method is useful to parse sequences that only match together which usually come in the form of chained Results with Result::and_then.

Examples

# use pest;
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {
    a
}

let input = "a";
let pairs: Vec<_> = pest::state(input, |state| {
    state.sequence(|s| {
        s.rule(Rule::a, |s| Ok(s)).and_then(|s| {
            s.match_string("b")
        })
    }).or_else(|s| {
        Ok(s)
    })
}).unwrap().collect();

assert_eq!(pairs.len(), 0);
fn repeat<F>(self: Box<Self>, f: F) -> ParseResult<Box<Self>>
where
    F: FnMut(Box<Self>) -> ParseResult<Box<Self>>

Repeatedly applies the transformation provided by f from the Box<ParserState>. Returns Ok with the updated Box<ParserState> returned by f wrapped up in an Err.

Examples

# use pest;
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {
    ab
}

let input = "aab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.repeat(|s| {
    s.match_string("a")
});
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 2);

state = pest::ParserState::new(input);
result = state.repeat(|s| {
    s.match_string("b")
});
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 0);
fn optional<F>(self: Box<Self>, f: F) -> ParseResult<Box<Self>>
where
    F: FnOnce(Box<Self>) -> ParseResult<Box<Self>>

Optionally applies the transformation provided by f from the Box<ParserState>. Returns Ok with the updated Box<ParserState> returned by f regardless of the Result.

Examples

# use pest;
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {
    ab
}

let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let result = state.optional(|s| {
    s.match_string("ab")
});
assert!(result.is_ok());

state = pest::ParserState::new(input);
let result = state.optional(|s| {
    s.match_string("ac")
});
assert!(result.is_ok());
fn match_char_by<F>(self: Box<Self>, f: F) -> ParseResult<Box<Self>>
where
    F: FnOnce(char) -> bool

Attempts to match a single character based on a filter function. Returns Ok with the updated Box<ParserState> if successful, or Err with the updated Box<ParserState> otherwise.

Examples

# use pest;
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {}

let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let result = state.match_char_by(|c| c.is_ascii());
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 1);

let input = "";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let result = state.match_char_by(|c| c.is_ascii());
assert!(result.is_err());
assert_eq!(result.unwrap_err().position().pos(), 0);
fn match_string(self: Box<Self>, string: &str) -> ParseResult<Box<Self>>

Attempts to match the given string. Returns Ok with the updated Box<ParserState> if successful, or Err with the updated Box<ParserState> otherwise.

Examples

# use pest;
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {}

let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.match_string("ab");
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 2);

state = pest::ParserState::new(input);
result = state.match_string("ac");
assert!(result.is_err());
assert_eq!(result.unwrap_err().position().pos(), 0);
fn stack_push_literal<impl Into<Cow<'static, str>>: Into<Cow<'static, str>>>(self: Box<Self>, string: impl Into<Cow<'static, str>>) -> ParseResult<Box<Self>>

Pushes the given literal to the stack, and always returns Ok(Box<ParserState>).

Examples

# use pest;
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {}

let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);

let mut result = state.stack_push_literal("a");
assert!(result.is_ok());
assert_eq!(result.as_ref().unwrap().position().pos(), 0);

let mut result = result.unwrap().stack_pop();
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 1);
fn match_insensitive(self: Box<Self>, string: &str) -> ParseResult<Box<Self>>

Attempts to case-insensitively match the given string. Returns Ok with the updated Box<ParserState> if successful, or Err with the updated Box<ParserState> otherwise.

Examples

# use pest;
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {}

let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.match_insensitive("AB");
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 2);

state = pest::ParserState::new(input);
result = state.match_insensitive("AC");
assert!(result.is_err());
assert_eq!(result.unwrap_err().position().pos(), 0);
fn match_range(self: Box<Self>, range: Range<char>) -> ParseResult<Box<Self>>

Attempts to match a single character from the given range. Returns Ok with the updated Box<ParserState> if successful, or Err with the updated Box<ParserState> otherwise.

Caution

The provided range is interpreted as inclusive.

Examples

# use pest;
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {}

let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.match_range('a'..'z');
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 1);

state = pest::ParserState::new(input);
result = state.match_range('A'..'Z');
assert!(result.is_err());
assert_eq!(result.unwrap_err().position().pos(), 0);
fn skip(self: Box<Self>, n: usize) -> ParseResult<Box<Self>>

Attempts to skip n characters forward. Returns Ok with the updated Box<ParserState> if successful, or Err with the updated Box<ParserState> otherwise.

Examples

# use pest;
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {}

let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.skip(1);
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 1);

state = pest::ParserState::new(input);
result = state.skip(3);
assert!(result.is_err());
assert_eq!(result.unwrap_err().position().pos(), 0);
fn skip_until(self: Box<Self>, strings: &[&str]) -> ParseResult<Box<Self>>

Attempts to skip forward until one of the given strings is found. Returns Ok with the updated Box<ParserState> whether or not one of the strings is found.

Examples

# use pest;
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {}

let input = "abcd";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.skip_until(&["c", "d"]);
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 2);
fn start_of_input(self: Box<Self>) -> ParseResult<Box<Self>>

Attempts to match the start of the input. Returns Ok with the current Box<ParserState> if the parser has not yet advanced, or Err with the current Box<ParserState> otherwise.

Examples

# use pest;
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {}

let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.start_of_input();
assert!(result.is_ok());

state = pest::ParserState::new(input);
state = state.match_string("ab").unwrap();
result = state.start_of_input();
assert!(result.is_err());
fn end_of_input(self: Box<Self>) -> ParseResult<Box<Self>>

Attempts to match the end of the input. Returns Ok with the current Box<ParserState> if there is no input remaining, or Err with the current Box<ParserState> otherwise.

Examples

# use pest;
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {}

let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.end_of_input();
assert!(result.is_err());

state = pest::ParserState::new(input);
state = state.match_string("ab").unwrap();
result = state.end_of_input();
assert!(result.is_ok());
fn lookahead<F>(self: Box<Self>, is_positive: bool, f: F) -> ParseResult<Box<Self>>
where
    F: FnOnce(Box<Self>) -> ParseResult<Box<Self>>

Starts a lookahead transformation provided by f from the Box<ParserState>. It returns Ok with the current Box<ParserState> if f also returns an Ok, or Err with the current Box<ParserState> otherwise. If is_positive is false, it swaps the Ok and Err together, negating the Result.

Examples

# use pest;
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {
    a
}

let input = "a";
let pairs: Vec<_> = pest::state(input, |state| {
    state.lookahead(true, |state| {
        state.rule(Rule::a, |s| Ok(s))
    })
}).unwrap().collect();

assert_eq!(pairs.len(), 0);
fn atomic<F>(self: Box<Self>, atomicity: Atomicity, f: F) -> ParseResult<Box<Self>>
where
    F: FnOnce(Box<Self>) -> ParseResult<Box<Self>>

Transformation which stops Tokens from being generated according to is_atomic. Used as wrapper over rule (or even another atomic) call.

Examples

# use pest::{self, Atomicity};
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {
    a
}

let input = "a";
let pairs: Vec<_> = pest::state(input, |state| {
    state.atomic(Atomicity::Atomic, |s| {
        s.rule(Rule::a, |s| Ok(s))
    })
}).unwrap().collect();

assert_eq!(pairs.len(), 0);
fn stack_push<F>(self: Box<Self>, f: F) -> ParseResult<Box<Self>>
where
    F: FnOnce(Box<Self>) -> ParseResult<Box<Self>>

Evaluates the result of closure f and pushes the span of the input consumed from before f is called to after f is called to the stack. Returns Ok(Box<ParserState>) if f is called successfully, or Err(Box<ParserState>) otherwise.

Examples

# use pest;
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {}

let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.stack_push(|state| state.match_string("a"));
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 1);
fn stack_peek(self: Box<Self>) -> ParseResult<Box<Self>>

Peeks the top of the stack and attempts to match the string. Returns Ok(Box<ParserState>) if the string is matched successfully, or Err(Box<ParserState>) otherwise.

Examples

# use pest;
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {}

let input = "aa";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.stack_push(|state| state.match_string("a")).and_then(
    |state| state.stack_peek()
);
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 2);
fn stack_pop(self: Box<Self>) -> ParseResult<Box<Self>>

Pops the top of the stack and attempts to match the string. Returns Ok(Box<ParserState>) if the string is matched successfully, or Err(Box<ParserState>) otherwise.

Examples

# use pest;
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {}

let input = "aa";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.stack_push(|state| state.match_string("a")).and_then(
    |state| state.stack_pop()
);
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 2);
fn stack_match_peek_slice(self: Box<Self>, start: i32, end: Option<i32>, match_dir: MatchDir) -> ParseResult<Box<Self>>

Matches part of the state of the stack.

Examples

# use pest::{self, MatchDir};
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {}

let input = "abcd cd cb";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state
    .stack_push(|state| state.match_string("a"))
    .and_then(|state| state.stack_push(|state| state.match_string("b")))
    .and_then(|state| state.stack_push(|state| state.match_string("c")))
    .and_then(|state| state.stack_push(|state| state.match_string("d")))
    .and_then(|state| state.match_string(" "))
    .and_then(|state| state.stack_match_peek_slice(2, None, MatchDir::BottomToTop))
    .and_then(|state| state.match_string(" "))
    .and_then(|state| state.stack_match_peek_slice(1, Some(-1), MatchDir::TopToBottom));
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 10);
fn stack_match_peek(self: Box<Self>) -> ParseResult<Box<Self>>

Matches the full state of the stack.

Examples

# use pest;
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {}

let input = "abba";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state
    .stack_push(|state| state.match_string("a"))
    .and_then(|state| { state.stack_push(|state| state.match_string("b")) })
    .and_then(|state| state.stack_match_peek());
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 4);
fn stack_match_pop(self: Box<Self>) -> ParseResult<Box<Self>>

Matches the full state of the stack. This method will clear the stack as it evaluates.

Examples

/// # use pest;
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {}

let input = "aaaa";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.stack_push(|state| state.match_string("a")).and_then(|state| {
    state.stack_push(|state| state.match_string("a"))
}).and_then(|state| state.stack_match_peek());
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 4);
fn stack_drop(self: Box<Self>) -> ParseResult<Box<Self>>

Drops the top of the stack. Returns Ok(Box<ParserState>) if there was a value to drop, or Err(Box<ParserState>) otherwise.

Examples

# use pest;
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {}

let input = "aa";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.stack_push(|state| state.match_string("a")).and_then(
    |state| state.stack_drop()
);
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 1);
fn restore_on_err<F>(self: Box<Self>, f: F) -> ParseResult<Box<Self>>
where
    F: FnOnce(Box<Self>) -> ParseResult<Box<Self>>

Restores the original state of the ParserState when f returns an Err. Currently, this method only restores the stack.

Examples

# use pest;
# #[allow(non_camel_case_types)]
# #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {}

let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.restore_on_err(|state| state.stack_push(|state|
    state.match_string("a")).and_then(|state| state.match_string("a"))
);

assert!(result.is_err());

// Since the the rule doesn't match, the "a" pushed to the stack will be removed.
let catch_panic = std::panic::catch_unwind(|| result.unwrap_err().stack_pop());
assert!(catch_panic.is_err());

impl<'i, R> Freeze for ParserState<'i, R>

impl<'i, R> RefUnwindSafe for ParserState<'i, R>

impl<'i, R> Send for ParserState<'i, R>

impl<'i, R> Sync for ParserState<'i, R>

impl<'i, R> Unpin for ParserState<'i, R>

impl<'i, R> UnsafeUnpin for ParserState<'i, R>

impl<'i, R> UnwindSafe for ParserState<'i, R>

impl<'i, R: $crate::fmt::Debug + RuleType> Debug for ParserState<'i, R>

fn fmt(self: &Self, f: &mut Formatter<'_>) -> Result

impl<T> Any for ParserState<'i, R>

fn type_id(self: &Self) -> TypeId

impl<T> Borrow for ParserState<'i, R>

fn borrow(self: &Self) -> &T

impl<T> BorrowMut for ParserState<'i, R>

fn borrow_mut(self: &mut Self) -> &mut T

impl<T> From for ParserState<'i, R>

fn from(t: T) -> T

Returns the argument unchanged.

impl<T, U> Into for ParserState<'i, R>

fn into(self: Self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

impl<T, U> TryFrom for ParserState<'i, R>

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

impl<T, U> TryInto for ParserState<'i, R>

fn try_into(self: Self) -> Result<U, <U as TryFrom<T>>::Error>