use serde_json::Number;
use super::super::{ast, lexer};
grammar<'i>;
extern {
type Location = lexer::Pos;
enum lexer::Token<'i> {
Fragment => lexer::Token::Fragment(<&'i str>),
"}}" => lexer::Token::BlockEnd,
"." => lexer::Token::Dot,
"," => lexer::Token::Comma,
"|!" => lexer::Token::PipeBang,
"|" => lexer::Token::Pipe,
"??" => lexer::Token::Coalesce,
"(" => lexer::Token::LParen,
")" => lexer::Token::RParen,
"[" => lexer::Token::LBrack,
"]" => lexer::Token::RBrack,
Ident => lexer::Token::Ident(<&'i str>),
Number => lexer::Token::Number(<Number>),
String => lexer::Token::String(<String>),
}
}
pub Format = <Segment*>;
Segment: ast::Segment<'i> = {
Fragment => ast::Segment::Fragment(<>),
Block => ast::Segment::Block(<>),
};
Block = <Expr?> "}}";
Expr: ast::Expr<'i> = {
NullChain => ast::Expr(Box::new(<>)),
};
NullChain: ast::NullChain<'i> = {
<l:NullChain> "??" <r:NullPipeline> => ast::NullChain::Chain(Box::new(l), r),
NullPipeline => ast::NullChain::Bang(<>),
};
NullPipeline: ast::NullPipeline<'i> = {
<l:NullPipeline> "|!" <r:Pipeline> => ast::NullPipeline::Bang(Box::new(l), r),
Pipeline => ast::NullPipeline::Pipe(<>),
};
Pipeline: ast::Pipeline<'i> = {
<l:Pipeline> "|" <r:Lens> => ast::Pipeline::Pipe(Box::new(l), r),
Lens => ast::Pipeline::Lens(<>),
};
Lens: ast::Lens<'i> = {
<l:Lens> "." <r:Ident> => ast::Lens::Dot(Box::new(l), r),
<l:Lens> "[" <r:Expr> "]" => ast::Lens::Index(Box::new(l), r),
Prim => ast::Lens::Prim(<>),
};
Prim: ast::Prim<'i> = {
"(" <Expr> ")" => ast::Prim::Paren(<>),
<Ident> "(" <Args?> ")" => ast::Prim::Call(<>),
"[" <Args?> "]" => ast::Prim::Array(<>),
Ident => ast::Prim::Ident(<>),
Number => ast::Prim::Value(<>.into()),
String => ast::Prim::Value(<>.into()),
};
Args: ast::Args<'i> = {
<l:Args> "," <r:Expr> => ast::Args::Comma(Box::new(l), r),
Expr => ast::Args::Expr(<>),
};