use std::convert::identity;
use chumsky::{
combinator::Repeated,
extra,
input::MappedSpan,
primitive::{any, just},
span::SimpleSpan,
text::Char,
IterParser, Parser,
};
use either::Either::{Left, Right};
use itertools::Itertools;
use crate::{__internal__parser, ast::SourceFile, Span};
use self::{
comments::{source_file_comment, source_file_comment_right_delimiter},
expression::expression,
};
use super::{with_span, Error};
mod command;
mod comments;
mod expression;
mod template;
mod ty;
mod type_definition;
#[cfg(test)]
mod test;
__internal__parser! {pub ident, &'s str, {
chumsky::text::ident().filter(|ident| !matches!(*ident, "if" | "else" | "each" | "select" | "in" | "template" | "type"))
}}
#[allow(clippy::type_complexity)]
fn source_file_whitespace_or_comments<'s, F: Fn(SimpleSpan) -> Span<'s> + 's>() -> Repeated<
impl Parser<'s, MappedSpan<Span<'s>, &'s str, F>, (), extra::Err<Error<'s>>> + Clone,
(),
MappedSpan<Span<'s>, &'s str, F>,
extra::Err<Error<'s>>,
> {
source_file_comment()
.or(any().filter(|ch: &char| ch.is_whitespace()).ignored())
.repeated()
}
#[allow(clippy::type_complexity)]
fn command_whitespace_or_comments<'s, F: Fn(SimpleSpan) -> Span<'s> + 's>() -> Repeated<
impl Parser<'s, MappedSpan<Span<'s>, &'s str, F>, (), extra::Err<Error<'s>>> + Clone,
(),
MappedSpan<Span<'s>, &'s str, F>,
extra::Err<Error<'s>>,
> {
source_file_comment_right_delimiter(just("}").ignored())
.or(any()
.filter(|ch: &char| ch.is_whitespace() && *ch != '}')
.ignored())
.repeated()
}
__internal__parser! {pub source_file, SourceFile<'s>, {
with_span(template::template(expression())).map(Left).or(with_span(type_definition::type_definition()).map(Right))
.padded_by(source_file_whitespace_or_comments())
.repeated()
.collect::<Vec<_>>()
.map(|templates_and_type_definitions| {
let (templates, type_defs): (Vec<_>, Vec<_>) = templates_and_type_definitions.into_iter().partition_map(identity);
SourceFile {
templates,
type_defs
}
})
}}