use std::collections::{HashMap, VecDeque}; use std::convert::From; use std::iter::Peekable; use std::str::FromStr; use pest::error::LineColLocation; use pest::iterators::Pair; use pest::{Parser, Position, Span}; use serde_json::value::Value as Json; use crate::error::{TemplateError, TemplateErrorReason}; use crate::grammar::{HandlebarsParser, Rule}; use crate::json::path::{parse_json_path_from_iter, Path}; use crate::support; use self::TemplateElement::*; #[derive(PartialEq, Eq, Clone, Debug)] pub struct TemplateMapping(pub usize, pub usize); /// A handlebars template #[derive(PartialEq, Eq, Clone, Debug, Default)] pub struct Template { pub name: Option, pub elements: Vec, pub mapping: Vec, } #[derive(Default)] pub(crate) struct TemplateOptions { pub(crate) prevent_indent: bool, pub(crate) name: Option, } impl TemplateOptions { fn name(&self) -> String { self.name .as_ref() .cloned() .unwrap_or_else(|| "Unnamed".to_owned()) } } #[derive(PartialEq, Eq, Clone, Debug)] pub struct Subexpression { // we use box here avoid resursive struct definition pub element: Box, } impl Subexpression { pub fn new( name: Parameter, params: Vec, hash: HashMap, ) -> Subexpression { Subexpression { element: Box::new(Expression(Box::new(HelperTemplate { name, params, hash, template: None, inverse: None, block_param: None, block: false, }))), } } pub fn is_helper(&self) -> bool { match *self.as_element() { TemplateElement::Expression(ref ht) => !ht.is_name_only(), _ => false, } } pub fn as_element(&self) -> &TemplateElement { self.element.as_ref() } pub fn name(&self) -> &str { match *self.as_element() { // FIXME: avoid unwrap here Expression(ref ht) => ht.name.as_name().unwrap(), _ => unreachable!(), } } pub fn params(&self) -> Option<&Vec> { match *self.as_element() { Expression(ref ht) => Some(&ht.params), _ => None, } } pub fn hash(&self) -> Option<&HashMap> { match *self.as_element() { Expression(ref ht) => Some(&ht.hash), _ => None, } } } #[derive(PartialEq, Eq, Clone, Debug)] pub enum BlockParam { Single(Parameter), Pair((Parameter, Parameter)), } #[derive(PartialEq, Eq, Clone, Debug)] pub struct ExpressionSpec { pub name: Parameter, pub params: Vec, pub hash: HashMap, pub block_param: Option, pub omit_pre_ws: bool, pub omit_pro_ws: bool, } #[derive(PartialEq, Eq, Clone, Debug)] pub enum Parameter { // for helper name only Name(String), // for expression, helper param and hash Path(Path), Literal(Json), Subexpression(Subexpression), } #[derive(PartialEq, Eq, Clone, Debug)] pub struct HelperTemplate { pub name: Parameter, pub params: Vec, pub hash: HashMap, pub block_param: Option, pub template: Option