pub mod any_token;
pub mod commit_matcher;
pub mod err_if;
pub mod error_contextualizer;
pub mod if_error;
pub mod ignore_result;
pub mod multiple;
pub mod negative_lookahead;
pub mod none_of;
pub mod one_or_more;
pub mod optional;
pub mod parser_matcher;
pub mod positive_lookahead;
pub(crate) mod runner;
pub mod sequence;
pub mod string;
pub mod to_parser;
pub use crate::error::MatcherRunError;
pub use any_token::AnyToken;
pub use commit_matcher::{CommitMatcher, commit_on};
pub use err_if::{
ErrIfMatchedMatcher, ErrIfNoMatchMatcher, err_if_matched, err_if_no_match,
try_insert_if_missing, unwanted,
};
pub use error_contextualizer::ErrorContextualizer;
pub use multiple::{Multiple, many};
pub use negative_lookahead::{NegativeLookahead, negative_lookahead};
pub use one_or_more::{OneOrMore, one_or_more};
pub use optional::{Optional, optional};
pub use parser_matcher::ParserMatcher;
pub use positive_lookahead::{PositiveLookahead, positive_lookahead};
pub(crate) use runner::{DirectMatchRunner, MatchRunner, NoMemoizeBacktrackingRunner};
pub use string::StringMatcher;
pub use to_parser::ToParser;
use std::{fmt::Display, ops::Deref, rc::Rc};
use crate::{
error::{MissingSyntax, UnwantedSyntax, error_handler::ErrorHandler},
input::{Input, InputStream},
};
pub(crate) mod internal {
use std::fmt::{Debug, Display};
use crate::{
error::{MatcherRunError, error_handler::ErrorHandler},
input::{Input, InputStream},
matcher::{MatcherCombinator, runner::MatchRunner},
};
pub trait MatcherImpl<'src, Inp, MRes>: Debug + MatcherCombinator + Clone
where
Inp: Input<'src>,
{
const CAN_MATCH_DIRECTLY: bool;
const CAN_MATCH_DIRECTLY_ASSUMING_NO_FAIL: bool = Self::CAN_MATCH_DIRECTLY;
const HAS_PROPERTY: bool;
const CAN_FAIL: bool;
fn match_with_runner<'a, Runner>(
&'a self,
runner: &mut Runner,
error_handler: &mut impl ErrorHandler,
input: &mut InputStream<'src, Inp>,
) -> Result<bool, MatcherRunError>
where
Runner: MatchRunner<'a, 'src, Inp, MRes = MRes>,
'src: 'a;
#[inline]
fn maybe_label(&self) -> Option<Box<dyn Display>> {
None
}
}
}
pub trait Matcher<'src, Inp: Input<'src>, MRes>: internal::MatcherImpl<'src, Inp, MRes> {}
pub trait MatcherCombinator {
#[cfg(feature = "parser-trace")]
#[track_caller]
fn add_error_info<Pars>(self, error_parser: Pars) -> ErrorContextualizer<Self, Pars>
where
Self: Sized,
{
ErrorContextualizer::new(self, error_parser)
}
#[cfg(not(feature = "parser-trace"))]
fn add_error_info<Pars>(self, error_parser: Pars) -> ErrorContextualizer<Self, Pars>
where
Self: Sized,
{
ErrorContextualizer::new(self, error_parser)
}
fn err_if_no_match<F>(self, factory: F) -> ErrIfNoMatchMatcher<Self, F>
where
Self: Sized,
{
ErrIfNoMatchMatcher::new(self, factory)
}
fn try_insert_if_missing<M: Display>(
self,
message: M,
) -> ErrIfNoMatchMatcher<Self, MissingSyntax>
where
Self: Sized,
{
self.err_if_no_match(MissingSyntax(message.to_string()))
}
fn err_if_matched<F>(self, factory: F) -> ErrIfMatchedMatcher<Self, F>
where
Self: Sized,
{
ErrIfMatchedMatcher::new(self, factory)
}
fn unwanted<M: Display>(self, message: M) -> ErrIfMatchedMatcher<Self, UnwantedSyntax>
where
Self: Sized,
{
self.err_if_matched(UnwantedSyntax(message.to_string()))
}
fn to<Output>(self, output: Output) -> ToParser<Self, Output>
where
Self: Sized,
{
ToParser::new(self, output)
}
}
impl<'src, Inp: Input<'src>, MRes, M> Matcher<'src, Inp, MRes> for M where
M: internal::MatcherImpl<'src, Inp, MRes>
{
}
impl<Inner> MatcherCombinator for &Inner where Inner: MatcherCombinator {}
impl<'src, Inp: Input<'src>, MRes, Inner> internal::MatcherImpl<'src, Inp, MRes> for &Inner
where
Inner: Matcher<'src, Inp, MRes>,
{
const CAN_MATCH_DIRECTLY: bool = Inner::CAN_MATCH_DIRECTLY;
const HAS_PROPERTY: bool = Inner::HAS_PROPERTY;
const CAN_FAIL: bool = Inner::CAN_FAIL;
#[inline]
fn match_with_runner<'a, Runner>(
&'a self,
runner: &mut Runner,
error_handler: &mut impl ErrorHandler,
input: &mut InputStream<'src, Inp>,
) -> Result<bool, MatcherRunError>
where
Runner: MatchRunner<'a, 'src, Inp, MRes = MRes>,
'src: 'a,
{
(**self).match_with_runner(runner, error_handler, input)
}
#[inline]
fn maybe_label(&self) -> Option<Box<dyn std::fmt::Display>> {
(**self).maybe_label()
}
}
impl<Inner> MatcherCombinator for Rc<Inner> where Inner: MatcherCombinator {}
impl<'src, Inp: Input<'src>, MRes, Inner> internal::MatcherImpl<'src, Inp, MRes> for Rc<Inner>
where
Inner: Matcher<'src, Inp, MRes>,
{
const CAN_MATCH_DIRECTLY: bool = Inner::CAN_MATCH_DIRECTLY;
const HAS_PROPERTY: bool = Inner::HAS_PROPERTY;
const CAN_FAIL: bool = Inner::CAN_FAIL;
#[inline]
fn match_with_runner<'a, Runner>(
&'a self,
runner: &mut Runner,
error_handler: &mut impl ErrorHandler,
input: &mut InputStream<'src, Inp>,
) -> Result<bool, MatcherRunError>
where
Runner: MatchRunner<'a, 'src, Inp, MRes = MRes>,
'src: 'a,
{
self.deref().match_with_runner(runner, error_handler, input)
}
#[inline]
fn maybe_label(&self) -> Option<Box<dyn std::fmt::Display>> {
self.deref().maybe_label()
}
}
impl<Inner> MatcherCombinator for Box<Inner> where Inner: MatcherCombinator {}
impl<'src, Inp: Input<'src>, MRes, Inner> internal::MatcherImpl<'src, Inp, MRes> for Box<Inner>
where
Inner: Matcher<'src, Inp, MRes>,
{
const CAN_MATCH_DIRECTLY: bool = Inner::CAN_MATCH_DIRECTLY;
const HAS_PROPERTY: bool = Inner::HAS_PROPERTY;
const CAN_FAIL: bool = Inner::CAN_FAIL;
#[inline]
fn match_with_runner<'a, Runner>(
&'a self,
runner: &mut Runner,
error_handler: &mut impl ErrorHandler,
input: &mut InputStream<'src, Inp>,
) -> Result<bool, MatcherRunError>
where
Runner: MatchRunner<'a, 'src, Inp, MRes = MRes>,
'src: 'a,
{
(**self).match_with_runner(runner, error_handler, input)
}
#[inline]
fn maybe_label(&self) -> Option<Box<dyn std::fmt::Display>> {
(**self).maybe_label()
}
}
impl MatcherCombinator for () {}
impl<'src, Inp: Input<'src>, MRes> internal::MatcherImpl<'src, Inp, MRes> for () {
const CAN_MATCH_DIRECTLY: bool = true;
const HAS_PROPERTY: bool = false;
const CAN_FAIL: bool = false;
#[inline(always)]
fn match_with_runner<'a, Runner>(
&'a self,
_runner: &mut Runner,
_error_handler: &mut impl ErrorHandler,
_input: &mut InputStream<'src, Inp>,
) -> Result<bool, MatcherRunError>
where
Runner: MatchRunner<'a, 'src, Inp, MRes = MRes>,
'src: 'a,
{
Ok(true)
}
}