peg_runtime/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2#![cfg_attr(feature = "unstable", feature(error_in_core))]
3
4use std::fmt::Display;
5
6pub mod error;
7mod slice;
8pub mod str;
9
10/// The result type used internally in the parser.
11///
12/// You'll only need this if implementing the `Parse*` traits for a custom input
13/// type, or using the `#{}` syntax to embed a custom Rust snippet within the parser.
14///
15/// The public API of a parser adapts errors to `std::result::Result` instead of using this type.
16#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
17pub enum RuleResult<T> {
18    /// Success, with final location
19    Matched(usize, T),
20
21    /// Failure (furthest failure location is not yet known)
22    Failed,
23}
24
25/// A type that can be used as input to a parser.
26#[allow(clippy::needless_lifetimes)]
27pub trait Parse {
28    type PositionRepr: Display;
29    fn start<'input>(&'input self) -> usize;
30    fn is_eof<'input>(&'input self, p: usize) -> bool;
31    fn position_repr<'input>(&'input self, p: usize) -> Self::PositionRepr;
32}
33
34/// A parser input type supporting the `[...]` syntax.
35pub trait ParseElem<'input>: Parse {
36    /// Type of a single atomic element of the input, for example a character or token
37    type Element: Copy;
38
39    /// Get the element at `pos`, or `Failed` if past end of input.
40    fn parse_elem(&'input self, pos: usize) -> RuleResult<Self::Element>;
41}
42
43/// A parser input type supporting the `"literal"` syntax.
44pub trait ParseLiteral: Parse {
45    /// Attempt to match the `literal` string at `pos`, returning whether it
46    /// matched or failed.
47    fn parse_string_literal(&self, pos: usize, literal: &str) -> RuleResult<()>;
48}
49
50/// A parser input type supporting the `$()` syntax.
51pub trait ParseSlice<'input>: Parse {
52    /// Type of a slice of the input.
53    type Slice;
54
55    /// Get a slice of input.
56    fn parse_slice(&'input self, p1: usize, p2: usize) -> Self::Slice;
57}
58
59#[cfg(not(feature = "std"))]
60extern crate alloc;
61#[cfg(not(feature = "std"))]
62extern crate core as std;
63
64// needed for type inference on the `#{|input, pos| ..}` closure, since there
65// are different type inference rules on closures in function args.
66#[doc(hidden)]
67pub fn call_custom_closure<I, T>(f: impl FnOnce(I, usize) -> RuleResult<T>, input: I, pos: usize) -> RuleResult<T> {
68    f(input, pos)
69}