xee-xpath-ast 0.1.4

XPath parser and AST implementation
Documentation
use chumsky::{input::ValueInput, prelude::*};

use xee_xpath_lexer::Token;

use crate::ast;
use crate::ast::Span;

use super::types::BoxedParser;

#[derive(Clone)]
pub(crate) struct ParserSignatureOutput<'a, I>
where
    I: ValueInput<'a, Token = Token<'a>, Span = Span>,
{
    pub(crate) param_list: BoxedParser<'a, I, Vec<ast::Param>>,
    pub(crate) signature: BoxedParser<'a, I, ast::Signature>,
}

pub(crate) fn parser_signature<'a, I>(
    eqname: BoxedParser<'a, I, ast::NameS>,
    sequence_type: BoxedParser<'a, I, ast::SequenceType>,
) -> ParserSignatureOutput<'a, I>
where
    I: ValueInput<'a, Token = Token<'a>, Span = Span>,
{
    let type_declaration = just(Token::As).ignore_then(sequence_type.clone()).boxed();

    let param = just(Token::Dollar)
        .ignore_then(eqname.clone())
        .then(type_declaration.clone().or_not())
        .map(|(name, type_)| ast::Param {
            name: name.value,
            type_,
        })
        .boxed();

    let param_list = param
        .separated_by(just(Token::Comma))
        .collect::<Vec<_>>()
        .boxed();

    let signature_param = just(Token::Dollar)
        .ignore_then(eqname.clone())
        .then(type_declaration.clone())
        .map(|(name, type_)| ast::SignatureParam {
            name: name.value,
            type_,
        })
        .boxed();

    let signature_param_list = signature_param
        .separated_by(just(Token::Comma))
        .collect::<Vec<_>>()
        .boxed();

    let signature = eqname
        .clone()
        .then(signature_param_list.delimited_by(just(Token::LeftParen), just(Token::RightParen)))
        .then_ignore(just(Token::As))
        .then(sequence_type.clone())
        .map(|((name, params), return_type)| ast::Signature {
            name,
            params,
            return_type,
        })
        .boxed();

    ParserSignatureOutput {
        param_list,
        signature,
    }
}