cookie_cutter_core 0.1.0

A feature-rich template engine with context aware escaping and both runtime and compiletime compilation
Documentation
use chumsky::{
    combinator::Repeated,
    extra,
    input::MappedSpan,
    primitive::{any, just},
    span::SimpleSpan,
    text::Char,
    IterParser, Parser,
};

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;

#[cfg(test)]
mod test;

__internal__parser! {pub ident, &'s str, {
    chumsky::text::ident().filter(|ident| !matches!(*ident, "if" | "else" | "each" | "in" | "template"))
}}

// chumsky types tend to get complicated and since this return type was auto generated it's fine
#[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()
}

// same here
#[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()))
            .padded_by(source_file_whitespace_or_comments())
            .repeated()
            .collect()
            .map(|templates| SourceFile { templates })
}}