use super::*;
pub struct End<I, E>(EmptyPhantom<(E, I)>);
pub const fn end<'src, I: Input<'src>, E: ParserExtra<'src, I>>() -> End<I, E> {
End(EmptyPhantom::new())
}
impl<I, E> Copy for End<I, E> {}
impl<I, E> Clone for End<I, E> {
fn clone(&self) -> Self {
*self
}
}
impl<'src, I, E> Parser<'src, I, (), E> for End<I, E>
where
I: Input<'src>,
E: ParserExtra<'src, I>,
{
#[inline]
fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, ()> {
let before = inp.save();
match inp.next_maybe_inner() {
None => Ok(M::bind(|| ())),
Some(tok) => {
let span = inp.span_since(before.cursor());
inp.rewind(before);
inp.add_alt([DefaultExpected::EndOfInput], Some(tok.into()), span);
Err(())
}
}
}
go_extra!(());
}
pub struct Empty<I, E>(EmptyPhantom<(E, I)>);
pub const fn empty<I, E>() -> Empty<I, E> {
Empty(EmptyPhantom::new())
}
impl<I, E> Copy for Empty<I, E> {}
impl<I, E> Clone for Empty<I, E> {
fn clone(&self) -> Self {
*self
}
}
impl<'src, I, E> Parser<'src, I, (), E> for Empty<I, E>
where
I: Input<'src>,
E: ParserExtra<'src, I>,
{
#[inline]
fn go<M: Mode>(&self, _: &mut InputRef<'src, '_, I, E>) -> PResult<M, ()> {
Ok(M::bind(|| ()))
}
go_extra!(());
}
pub struct JustCfg<T> {
seq: Option<T>,
}
impl<T> JustCfg<T> {
#[inline]
pub fn seq(mut self, new_seq: T) -> Self {
self.seq = Some(new_seq);
self
}
}
impl<T> Default for JustCfg<T> {
#[inline]
fn default() -> Self {
JustCfg { seq: None }
}
}
pub struct Just<T, I, E = EmptyErr> {
seq: T,
#[allow(dead_code)]
phantom: EmptyPhantom<(E, I)>,
}
impl<T: Copy, I, E> Copy for Just<T, I, E> {}
impl<T: Clone, I, E> Clone for Just<T, I, E> {
fn clone(&self) -> Self {
Self {
seq: self.seq.clone(),
phantom: EmptyPhantom::new(),
}
}
}
pub const fn just<'src, T, I, E>(seq: T) -> Just<T, I, E>
where
I: Input<'src>,
E: ParserExtra<'src, I>,
I::Token: PartialEq,
T: OrderedSeq<'src, I::Token> + Clone,
{
Just {
seq,
phantom: EmptyPhantom::new(),
}
}
impl<'src, I, E, T> Parser<'src, I, T, E> for Just<T, I, E>
where
I: Input<'src>,
E: ParserExtra<'src, I>,
I::Token: PartialEq,
T: OrderedSeq<'src, I::Token> + Clone,
{
#[doc(hidden)]
#[cfg(feature = "debug")]
fn node_info(&self, scope: &mut debug::NodeScope) -> debug::NodeInfo {
debug::NodeInfo::Just(self.seq.seq_info(scope))
}
#[inline]
fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, T> {
Self::go_cfg::<M>(self, inp, JustCfg::default())
}
go_extra!(T);
}
impl<'src, I, E, T> ConfigParser<'src, I, T, E> for Just<T, I, E>
where
I: Input<'src>,
E: ParserExtra<'src, I>,
I::Token: PartialEq,
T: OrderedSeq<'src, I::Token> + Clone,
{
type Config = JustCfg<T>;
#[inline]
fn go_cfg<M: Mode>(
&self,
inp: &mut InputRef<'src, '_, I, E>,
cfg: Self::Config,
) -> PResult<M, T> {
let seq = cfg.seq.as_ref().unwrap_or(&self.seq);
for next in seq.seq_iter() {
let before = inp.save();
match inp.next_maybe_inner() {
Some(tok) if next.borrow() == tok.borrow() => {}
found => {
let span = inp.span_since(before.cursor());
inp.rewind(before);
inp.add_alt(
[DefaultExpected::Token(T::to_maybe_ref(next))],
found.map(|f| f.into()),
span,
);
return Err(());
}
}
}
Ok(M::bind(|| seq.clone()))
}
}
pub struct OneOf<T, I, E> {
seq: T,
#[allow(dead_code)]
phantom: EmptyPhantom<(E, I)>,
}
impl<T: Copy, I, E> Copy for OneOf<T, I, E> {}
impl<T: Clone, I, E> Clone for OneOf<T, I, E> {
fn clone(&self) -> Self {
Self {
seq: self.seq.clone(),
phantom: EmptyPhantom::new(),
}
}
}
pub const fn one_of<'src, T, I, E>(seq: T) -> OneOf<T, I, E>
where
I: ValueInput<'src>,
E: ParserExtra<'src, I>,
I::Token: PartialEq,
T: Seq<'src, I::Token>,
{
OneOf {
seq,
phantom: EmptyPhantom::new(),
}
}
impl<'src, I, E, T> Parser<'src, I, I::Token, E> for OneOf<T, I, E>
where
I: ValueInput<'src>,
E: ParserExtra<'src, I>,
I::Token: PartialEq,
T: Seq<'src, I::Token>,
{
#[doc(hidden)]
#[cfg(feature = "debug")]
fn node_info(&self, scope: &mut debug::NodeScope) -> debug::NodeInfo {
debug::NodeInfo::OneOf(self.seq.seq_info(scope))
}
#[inline]
fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, I::Token> {
let before = inp.save();
match inp.next_inner() {
#[allow(suspicious_double_ref_op)] Some(tok) if self.seq.contains(tok.borrow()) => Ok(M::bind(|| tok)),
found => {
let err_span = inp.span_since(before.cursor());
inp.rewind(before);
inp.add_alt(
self.seq
.seq_iter()
.map(|e| DefaultExpected::Token(T::to_maybe_ref(e))),
found.map(|f| f.into()),
err_span,
);
Err(())
}
}
}
go_extra!(I::Token);
}
pub struct NoneOf<T, I, E> {
seq: T,
#[allow(dead_code)]
phantom: EmptyPhantom<(E, I)>,
}
impl<T: Copy, I, E> Copy for NoneOf<T, I, E> {}
impl<T: Clone, I, E> Clone for NoneOf<T, I, E> {
fn clone(&self) -> Self {
Self {
seq: self.seq.clone(),
phantom: EmptyPhantom::new(),
}
}
}
pub const fn none_of<'src, T, I, E>(seq: T) -> NoneOf<T, I, E>
where
I: ValueInput<'src>,
E: ParserExtra<'src, I>,
I::Token: PartialEq,
T: Seq<'src, I::Token>,
{
NoneOf {
seq,
phantom: EmptyPhantom::new(),
}
}
impl<'src, I, E, T> Parser<'src, I, I::Token, E> for NoneOf<T, I, E>
where
I: ValueInput<'src>,
E: ParserExtra<'src, I>,
I::Token: PartialEq,
T: Seq<'src, I::Token>,
{
#[doc(hidden)]
#[cfg(feature = "debug")]
fn node_info(&self, scope: &mut debug::NodeScope) -> debug::NodeInfo {
debug::NodeInfo::NoneOf(self.seq.seq_info(scope))
}
#[inline]
fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, I::Token> {
let before = inp.save();
match inp.next_inner() {
Some(tok) if !self.seq.contains(tok.borrow()) => Ok(M::bind(|| tok)),
found => {
let err_span = inp.span_since(before.cursor());
inp.rewind(before);
inp.add_alt(
[DefaultExpected::SomethingElse],
found.map(|f| f.into()),
err_span,
);
Err(())
}
}
}
go_extra!(I::Token);
}
pub struct Custom<F, I, O, E> {
f: F,
#[allow(dead_code)]
phantom: EmptyPhantom<(E, O, I)>,
}
impl<F: Copy, I, O, E> Copy for Custom<F, I, O, E> {}
impl<F: Clone, I, O, E> Clone for Custom<F, I, O, E> {
fn clone(&self) -> Self {
Self {
f: self.f.clone(),
phantom: EmptyPhantom::new(),
}
}
}
pub const fn custom<'src, F, I, O, E>(f: F) -> Custom<F, I, O, E>
where
I: Input<'src>,
E: ParserExtra<'src, I>,
F: Fn(&mut InputRef<'src, '_, I, E>) -> Result<O, E::Error>,
{
Custom {
f,
phantom: EmptyPhantom::new(),
}
}
impl<'src, I, O, E, F> Parser<'src, I, O, E> for Custom<F, I, O, E>
where
I: Input<'src>,
E: ParserExtra<'src, I>,
F: Fn(&mut InputRef<'src, '_, I, E>) -> Result<O, E::Error>,
{
#[inline]
fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, O> {
let before = inp.cursor();
match (self.f)(inp) {
Ok(out) => Ok(M::bind(|| out)),
Err(err) => {
inp.add_alt_err(&before.inner, err);
Err(())
}
}
}
go_extra!(O);
}
pub struct Select<F, I, O, E> {
filter: F,
#[allow(dead_code)]
phantom: EmptyPhantom<(E, O, I)>,
}
impl<F: Copy, I, O, E> Copy for Select<F, I, O, E> {}
impl<F: Clone, I, O, E> Clone for Select<F, I, O, E> {
fn clone(&self) -> Self {
Self {
filter: self.filter.clone(),
phantom: EmptyPhantom::new(),
}
}
}
pub const fn select<'src, F, I, O, E>(filter: F) -> Select<F, I, O, E>
where
I: Input<'src>,
I::Token: Clone + 'src,
E: ParserExtra<'src, I>,
F: Fn(I::Token, &mut MapExtra<'src, '_, I, E>) -> Option<O>,
{
Select {
filter,
phantom: EmptyPhantom::new(),
}
}
impl<'src, I, O, E, F> Parser<'src, I, O, E> for Select<F, I, O, E>
where
I: Input<'src>,
I::Token: Clone + 'src,
E: ParserExtra<'src, I>,
F: Fn(I::Token, &mut MapExtra<'src, '_, I, E>) -> Option<O>,
{
#[doc(hidden)]
#[cfg(feature = "debug")]
fn node_info(&self, _scope: &mut debug::NodeScope) -> debug::NodeInfo {
debug::NodeInfo::Filter(Box::new(debug::NodeInfo::Any))
}
#[inline]
fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, O> {
let before = inp.save();
let next = inp.next_maybe_inner();
let found = match next {
Some(tok) => {
match (self.filter)(
tok.borrow().clone(),
&mut MapExtra::new(before.cursor(), inp),
) {
Some(out) => return Ok(M::bind(|| out)),
None => Some(tok.into()),
}
}
found => found.map(|f| f.into()),
};
let err_span = inp.span_since(before.cursor());
inp.rewind(before);
inp.add_alt([DefaultExpected::SomethingElse], found, err_span);
Err(())
}
go_extra!(O);
}
pub struct SelectRef<F, I, O, E> {
filter: F,
#[allow(dead_code)]
phantom: EmptyPhantom<(E, O, I)>,
}
impl<F: Copy, I, O, E> Copy for SelectRef<F, I, O, E> {}
impl<F: Clone, I, O, E> Clone for SelectRef<F, I, O, E> {
fn clone(&self) -> Self {
Self {
filter: self.filter.clone(),
phantom: EmptyPhantom::new(),
}
}
}
pub const fn select_ref<'src, F, I, O, E>(filter: F) -> SelectRef<F, I, O, E>
where
I: BorrowInput<'src>,
I::Token: 'src,
E: ParserExtra<'src, I>,
F: Fn(&'src I::Token, &mut MapExtra<'src, '_, I, E>) -> Option<O>,
{
SelectRef {
filter,
phantom: EmptyPhantom::new(),
}
}
impl<'src, I, O, E, F> Parser<'src, I, O, E> for SelectRef<F, I, O, E>
where
I: BorrowInput<'src>,
I::Token: 'src,
E: ParserExtra<'src, I>,
F: Fn(&'src I::Token, &mut MapExtra<'src, '_, I, E>) -> Option<O>,
{
#[inline]
fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, O> {
let before = inp.save();
let next = inp.next_ref_inner();
let found = match next {
Some(tok) => match (self.filter)(tok, &mut MapExtra::new(before.cursor(), inp)) {
Some(out) => return Ok(M::bind(|| out)),
None => Some(tok.into()),
},
found => found.map(|f| f.into()),
};
let err_span = inp.span_since(before.cursor());
inp.rewind(before);
inp.add_alt([DefaultExpected::SomethingElse], found, err_span);
Err(())
}
go_extra!(O);
}
pub struct Any<I, E> {
#[allow(dead_code)]
phantom: EmptyPhantom<(E, I)>,
}
impl<I, E> Copy for Any<I, E> {}
impl<I, E> Clone for Any<I, E> {
fn clone(&self) -> Self {
*self
}
}
impl<'src, I, E> Parser<'src, I, I::Token, E> for Any<I, E>
where
I: ValueInput<'src>,
E: ParserExtra<'src, I>,
{
#[doc(hidden)]
#[cfg(feature = "debug")]
fn node_info(&self, _scope: &mut debug::NodeScope) -> debug::NodeInfo {
debug::NodeInfo::Any
}
#[inline]
fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, I::Token> {
let before = inp.save();
match inp.next_inner() {
Some(tok) => Ok(M::bind(|| tok)),
found => {
let err_span = inp.span_since(before.cursor());
inp.rewind(before);
inp.add_alt([DefaultExpected::Any], found.map(|f| f.into()), err_span);
Err(())
}
}
}
go_extra!(I::Token);
}
pub const fn any<'src, I: Input<'src>, E: ParserExtra<'src, I>>() -> Any<I, E> {
Any {
phantom: EmptyPhantom::new(),
}
}
pub struct AnyRef<I, E> {
#[allow(dead_code)]
phantom: EmptyPhantom<(E, I)>,
}
impl<I, E> Copy for AnyRef<I, E> {}
impl<I, E> Clone for AnyRef<I, E> {
fn clone(&self) -> Self {
*self
}
}
impl<'src, I, E> Parser<'src, I, &'src I::Token, E> for AnyRef<I, E>
where
I: BorrowInput<'src>,
E: ParserExtra<'src, I>,
{
#[inline]
fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, &'src I::Token> {
let before = inp.save();
match inp.next_ref_inner() {
Some(tok) => Ok(M::bind(|| tok)),
found => {
let err_span = inp.span_since(before.cursor());
inp.rewind(before);
inp.add_alt([DefaultExpected::Any], found.map(|f| f.into()), err_span);
Err(())
}
}
}
go_extra!(&'src I::Token);
}
pub const fn any_ref<'src, I: BorrowInput<'src>, E: ParserExtra<'src, I>>() -> AnyRef<I, E> {
AnyRef {
phantom: EmptyPhantom::new(),
}
}
pub struct MapCtx<A, AE, F, E> {
pub(crate) parser: A,
pub(crate) mapper: F,
#[allow(dead_code)]
pub(crate) phantom: EmptyPhantom<(AE, E)>,
}
impl<A: Copy, AE, F: Copy, E> Copy for MapCtx<A, AE, F, E> {}
impl<A: Clone, AE, F: Clone, E> Clone for MapCtx<A, AE, F, E> {
fn clone(&self) -> Self {
MapCtx {
parser: self.parser.clone(),
mapper: self.mapper.clone(),
phantom: EmptyPhantom::new(),
}
}
}
impl<'src, I, O, E, EI, A, F> Parser<'src, I, O, E> for MapCtx<A, EI, F, E>
where
I: Input<'src>,
E: ParserExtra<'src, I>,
EI: ParserExtra<'src, I, Error = E::Error, State = E::State>,
A: Parser<'src, I, O, EI>,
F: Fn(&E::Context) -> EI::Context,
EI::Context: 'src,
{
#[inline]
fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, O> {
inp.with_ctx(&(self.mapper)(inp.ctx()), |inp| self.parser.go::<M>(inp))
}
go_extra!(O);
}
pub const fn map_ctx<'src, P, OP, I, E, EP, F>(mapper: F, parser: P) -> MapCtx<P, EP, F, E>
where
F: Fn(&E::Context) -> EP::Context,
I: Input<'src>,
P: Parser<'src, I, OP, EP>,
E: ParserExtra<'src, I>,
EP: ParserExtra<'src, I>,
EP::Context: 'src,
{
MapCtx {
parser,
mapper,
phantom: EmptyPhantom::new(),
}
}
pub struct Todo<I, O, E> {
location: Location<'static>,
#[allow(dead_code)]
phantom: EmptyPhantom<(O, E, I)>,
}
impl<I, O, E> Copy for Todo<I, O, E> {}
impl<I, O, E> Clone for Todo<I, O, E> {
fn clone(&self) -> Self {
*self
}
}
#[track_caller]
pub fn todo<'src, I: Input<'src>, O, E: ParserExtra<'src, I>>() -> Todo<I, O, E> {
Todo {
location: *Location::caller(),
phantom: EmptyPhantom::new(),
}
}
impl<'src, I, O, E> Parser<'src, I, O, E> for Todo<I, O, E>
where
I: Input<'src>,
E: ParserExtra<'src, I>,
{
#[inline]
fn go<M: Mode>(&self, _inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, O> {
todo!(
"Attempted to use an unimplemented parser at {}",
self.location
)
}
go_extra!(O);
}
#[derive(Copy, Clone)]
pub struct Choice<T> {
parsers: T,
}
pub const fn choice<T>(parsers: T) -> Choice<T> {
Choice { parsers }
}
macro_rules! impl_choice_for_tuple {
() => {};
($head:ident $($X:ident)*) => {
impl_choice_for_tuple!($($X)*);
impl_choice_for_tuple!(~ $head $($X)*);
};
(~ $Head:ident $($X:ident)+) => {
#[allow(unused_variables, non_snake_case)]
impl<'src, I, E, $Head, $($X),*, O> Parser<'src, I, O, E> for Choice<($Head, $($X,)*)>
where
I: Input<'src>,
E: ParserExtra<'src, I>,
$Head: Parser<'src, I, O, E>,
$($X: Parser<'src, I, O, E>),*
{
#[doc(hidden)]
#[cfg(feature = "debug")]
fn node_info(&self, scope: &mut debug::NodeScope) -> debug::NodeInfo {
let Choice { parsers: ($Head, $($X,)*), .. } = self;
debug::NodeInfo::Choice(vec![$Head.node_info(scope), $($X.node_info(scope)),*])
}
#[inline]
fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, O> {
let before = inp.save();
let Choice { parsers: ($Head, $($X,)*), .. } = self;
match $Head.go::<M>(inp) {
Ok(out) => return Ok(out),
Err(()) => inp.rewind(before.clone()),
}
$(
match $X.go::<M>(inp) {
Ok(out) => return Ok(out),
Err(()) => inp.rewind(before.clone()),
}
)*
Err(())
}
go_extra!(O);
}
};
(~ $Head:ident) => {
impl<'src, I, E, $Head, O> Parser<'src, I, O, E> for Choice<($Head,)>
where
I: Input<'src>,
E: ParserExtra<'src, I>,
$Head: Parser<'src, I, O, E>,
{
#[inline]
fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, O> {
self.parsers.0.go::<M>(inp)
}
go_extra!(O);
}
};
}
impl_choice_for_tuple!(A_ B_ C_ D_ E_ F_ G_ H_ I_ J_ K_ L_ M_ N_ O_ P_ Q_ R_ S_ T_ U_ V_ W_ X_ Y_ Z_);
impl<'src, A, I, O, E> Parser<'src, I, O, E> for Choice<&[A]>
where
A: Parser<'src, I, O, E>,
I: Input<'src>,
E: ParserExtra<'src, I>,
{
#[inline]
fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, O> {
if self.parsers.is_empty() {
let offs = inp.cursor();
let err_span = inp.span_since(&offs);
inp.add_alt([], None, err_span);
Err(())
} else {
let before = inp.save();
for parser in self.parsers.iter() {
inp.rewind(before.clone());
if let Ok(out) = parser.go::<M>(inp) {
return Ok(out);
}
}
Err(())
}
}
go_extra!(O);
}
impl<'src, A, I, O, E> Parser<'src, I, O, E> for Choice<Vec<A>>
where
A: Parser<'src, I, O, E>,
I: Input<'src>,
E: ParserExtra<'src, I>,
{
#[inline]
fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, O> {
choice(&self.parsers[..]).go::<M>(inp)
}
go_extra!(O);
}
impl<'src, A, I, O, E, const N: usize> Parser<'src, I, O, E> for Choice<[A; N]>
where
A: Parser<'src, I, O, E>,
I: Input<'src>,
E: ParserExtra<'src, I>,
{
#[inline]
fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, O> {
choice(&self.parsers[..]).go::<M>(inp)
}
go_extra!(O);
}
#[derive(Copy, Clone)]
pub struct Group<T> {
parsers: T,
}
pub const fn group<T>(parsers: T) -> Group<T> {
Group { parsers }
}
impl<'src, I, O, E, P, const N: usize> Parser<'src, I, [O; N], E> for Group<[P; N]>
where
I: Input<'src>,
E: ParserExtra<'src, I>,
P: Parser<'src, I, O, E>,
{
#[inline]
fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, [O; N]> {
let mut arr: [MaybeUninit<_>; N] = MaybeUninitExt::uninit_array();
self.parsers
.iter()
.zip(arr.iter_mut())
.try_for_each(|(p, res)| {
res.write(p.go::<M>(inp)?);
Ok(())
})?;
Ok(M::array(unsafe { MaybeUninitExt::array_assume_init(arr) }))
}
go_extra!([O; N]);
}
macro_rules! flatten_map {
(<$M:ident> $head:ident) => {
$M::map(
$head,
|$head| ($head,),
)
};
(<$M:ident> $head1:ident $head2:ident) => {
$M::combine(
$head1,
$head2,
|$head1, $head2| ($head1, $head2),
)
};
(<$M:ident> $head:ident $($X:ident)+) => {
$M::combine(
$head,
flatten_map!(
<$M>
$($X)+
),
|$head, ($($X),+)| ($head, $($X),+),
)
};
}
macro_rules! impl_group_for_tuple {
() => {};
($head:ident $ohead:ident $($X:ident $O:ident)*) => {
impl_group_for_tuple!($($X $O)*);
impl_group_for_tuple!(~ $head $ohead $($X $O)*);
};
(~ $($X:ident $O:ident)*) => {
#[allow(unused_variables, non_snake_case)]
impl<'src, I, E, $($X),*, $($O),*> Parser<'src, I, ($($O,)*), E> for Group<($($X,)*)>
where
I: Input<'src>,
E: ParserExtra<'src, I>,
$($X: Parser<'src, I, $O, E>),*
{
#[inline]
fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, ($($O,)*)> {
let Group { parsers: ($($X,)*) } = self;
$(
let $X = $X.go::<M>(inp)?;
)*
Ok(flatten_map!(<M> $($X)*))
}
go_extra!(($($O,)*));
}
};
}
impl_group_for_tuple! {
A_ OA
B_ OB
C_ OC
D_ OD
E_ OE
F_ OF
G_ OG
H_ OH
I_ OI
J_ OJ
K_ OK
L_ OL
M_ OM
N_ ON
O_ OO
P_ OP
Q_ OQ
R_ OR
S_ OS
T_ OT
U_ OU
V_ OV
W_ OW
X_ OX
Y_ OY
Z_ OZ
}
#[derive(Copy, Clone)]
pub struct Set<T> {
parsers: T,
}
pub const fn set<T>(parsers: T) -> Set<T> {
Set { parsers }
}
fn go_or_finish<'src, O, I, E, P, M>(
item: &mut Option<M::Output<O>>,
parser: &P,
inp: &mut InputRef<'src, '_, I, E>,
) -> PResult<M, ()>
where
I: Input<'src>,
E: ParserExtra<'src, I>,
P: Parser<'src, I, O, E>,
M: Mode,
{
if item.is_none() {
match parser.go::<M>(inp) {
Ok(out) => {
*item = Some(out);
}
Err(()) => {
return Err(());
}
}
}
Ok(M::bind(|| ()))
}
fn go_or_rewind<'src, O, I, E, P, M>(
item: &mut Option<M::Output<O>>,
parser: &P,
inp: &mut InputRef<'src, '_, I, E>,
) where
I: Input<'src>,
E: ParserExtra<'src, I>,
P: Parser<'src, I, O, E>,
M: Mode,
{
if item.is_none() {
let save_before = inp.save();
let pos_before = inp.cursor();
match parser.go::<M>(inp) {
Ok(out) => {
if pos_before == inp.cursor() {
inp.rewind(save_before.clone());
} else {
*item = Some(out);
}
}
Err(()) => inp.rewind(save_before.clone()),
}
}
}
macro_rules! impl_set_for_tuple {
() => {};
($head_1:ident $head_2:ident $head_3:ident $($X:ident)*) => {
impl_set_for_tuple!($($X)*);
impl_set_for_tuple!(~ $head_1 $head_2 $head_3 $($X)*);
};
(~ $($O:ident $P:ident $I:ident)+) => {
#[allow(unused_variables, non_snake_case)]
impl<'src, I, E, $($P),*, $($O,)*> Parser<'src, I, ($($O,)*), E> for Set<($($P,)*)>
where
I: Input<'src>,
E: ParserExtra<'src, I>,
$($P: Parser<'src, I, $O, E>),*
{
#[inline]
fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, ($($O,)*)> {
let Set { parsers: ($($P,)*), .. } = self;
$( let mut $I: Option<M::Output<$O>> = None; )*
loop {
let start = inp.cursor();
$( go_or_rewind::<_, _, _, _, M>(&mut $I, $P, inp); )*
if start == inp.cursor() {
break;
}
}
$( go_or_finish::<_, _, _, _, M>(&mut $I, $P, inp)?; )*
$( let $I = $I.unwrap(); )*
Ok(flatten_map!(<M> $($I)*))
}
go_extra!(($($O,)*));
}
};
}
impl_set_for_tuple!(A1 A2 A3 B1 B2 B3 C1 C2 C3 D1 D2 D3 E1 E2 E3 F1 F2 F3 G1 G2 G3 H1 H2 H3 I1 I2 I3 J1 J2 J3 K1 K2 K3 L1 L2 L3 M1 M2 M3 N1 N2 N3 O1 O2 O3 P1 P2 P3 Q1 Q2 Q3 R1 R2 R3 S1 S2 S3 T1 T2 T3 U1 U2 U3 V1 V2 V3 W1 W2 W3 X1 X2 X3 Y1 Y2 Y3 Z1 Z2 Z3);
impl<'src, P, I, O, E> Parser<'src, I, Vec<O>, E> for Set<Vec<P>>
where
P: Parser<'src, I, O, E>,
I: Input<'src>,
E: ParserExtra<'src, I>,
{
#[inline]
fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, Vec<O>> {
let mut tmp = self
.parsers
.iter()
.map(|_| None)
.collect::<Vec<Option<M::Output<O>>>>();
loop {
let start = inp.cursor();
for (i, parser) in self.parsers.iter().enumerate() {
go_or_rewind::<_, _, _, _, M>(&mut tmp[i], parser, inp);
}
if start == inp.cursor() {
break;
}
}
for (i, parser) in self.parsers.iter().enumerate() {
go_or_finish::<_, _, _, _, M>(&mut tmp[i], parser, inp)?;
}
let mut result = M::bind(|| Vec::new());
tmp.into_iter()
.for_each(|x| M::combine_mut(&mut result, x.unwrap(), |result, x| result.push(x)));
Ok(result)
}
go_extra!(Vec<O>);
}
impl<'src, P, I, O, E, const N: usize> Parser<'src, I, [O; N], E> for Set<[P; N]>
where
P: Parser<'src, I, O, E>,
I: Input<'src>,
E: ParserExtra<'src, I>,
O: Copy,
{
#[inline]
fn go<M: Mode>(&self, inp: &mut InputRef<'src, '_, I, E>) -> PResult<M, [O; N]> {
let mut tmp: [Option<O>; N] = [None; N];
loop {
let start = inp.cursor();
for (i, parser) in self.parsers.iter().enumerate() {
go_or_rewind::<_, _, _, _, Emit>(&mut tmp[i], parser, inp);
}
if start == inp.cursor() {
break;
}
}
for (i, parser) in self.parsers.iter().enumerate() {
go_or_finish::<_, _, _, _, Emit>(&mut tmp[i], parser, inp)?;
}
Ok(M::bind(|| tmp.map(|x| x.unwrap())))
}
go_extra!([O; N]);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn set_parser() {
fn just(s: &str) -> Just<&str, &str, extra::Err<EmptyErr>> {
super::just(s)
}
let parser = set((just("abc"), just("def"), just("ijk")));
assert_eq!(
parser.parse("ijkdefabc").into_result(),
Ok(("abc", "def", "ijk")),
);
assert_eq!(
parser.parse("abcdefijk").into_result(),
Ok(("abc", "def", "ijk")),
);
let parser = set((choice((just("abc"), just("def"))), just("abc")));
assert_eq!(parser.parse("defabc").into_result(), Ok(("def", "abc")),);
let parser = set((choice((just("abc"), just("def"))), just("abc")));
assert!(parser.parse("abcdef").into_result().is_err());
let parser = set((
just("abc").or_not(),
just("def").or_not(),
just("ijk").or_not(),
));
assert_eq!(
parser.parse("ijkdefabc").into_result(),
Ok((Some("abc"), Some("def"), Some("ijk"))),
);
assert_eq!(
parser.parse("ijkabc").into_result(),
Ok((Some("abc"), None, Some("ijk"))),
);
assert_eq!(parser.parse("").into_result(), Ok((None, None, None)),);
let parser = set(vec![just("abc"), just("def"), just("ijk")]);
assert_eq!(
parser.parse("ijkdefabc").into_result(),
Ok(vec!["abc", "def", "ijk"]),
);
let parser = set([just("abc"), just("def"), just("ijk")]);
assert_eq!(
parser.parse("ijkdefabc").into_result(),
Ok(["abc", "def", "ijk"]),
);
}
}