use std::fmt::{Display, Formatter};
pub use crate::ast_context_iter::AstContextIterator;
pub use crate::ast_context_iter::IteratorContext;
pub use crate::ast_iter::AstIterator;
#[derive(Debug, Eq, PartialEq, Clone)]
pub enum SyntaxNode {
Root(Vec<SyntaxNode>),
Tag(Tag),
Plain(Plain),
Whitespace,
HtmlComment(HtmlComment),
OutputExpression(OutputExpression),
TwigComment(TwigComment),
TwigStatement(TwigStatement),
TwigStructure(TwigStructure<SyntaxNode>),
}
impl SyntaxNode {
pub fn is_whitespace(&self) -> bool {
if let SyntaxNode::Whitespace = self {
return true;
}
false
}
}
#[derive(Debug, Eq, PartialEq, Clone)]
pub enum TwigStatement {
Raw(String),
}
#[derive(Debug, Eq, PartialEq, Clone)]
pub enum TwigStructure<C> {
TwigBlock(TwigBlock<C>),
TwigFor(TwigFor<C>),
TwigIf(TwigIf<C>),
TwigApply(TwigApply<C>),
TwigSetCapture(TwigSetCapture<C>),
}
impl Display for TwigStructure<TagAttribute> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
TwigStructure::TwigBlock(t) => {
write!(f, "{{% block {} %}}", t.name)?;
for child in &t.children {
write!(f, " {}", child)?;
}
write!(f, "{{% endblock %}}")
}
TwigStructure::TwigFor(t) => {
write!(f, "{{% for {} %}}", t.expression)?;
for child in &t.children {
write!(f, " {}", child)?;
}
write!(f, "{{% endfor %}}")
}
TwigStructure::TwigIf(t) => {
for (i, arm) in t.if_arms.iter().enumerate() {
match (i, &arm.expression) {
(0, Some(expr)) => write!(f, "{{% if {} %}}", expr),
(_, Some(expr)) => write!(f, "{{% elseif {} %}}", expr),
(_, None) => write!(f, "{{% else %}}"),
}?;
for child in &arm.children {
write!(f, " {}", child)?;
}
write!(f, " ")?;
}
write!(f, "{{% endif %}}")
}
TwigStructure::TwigApply(t) => {
write!(f, "{{% apply {} %}}", t.expression)?;
for child in &t.children {
write!(f, " {}", child)?;
}
write!(f, "{{% endapply %}}")
}
TwigStructure::TwigSetCapture(t) => {
write!(f, "{{% set {} %}}", t.name)?;
for child in &t.children {
write!(f, " {}", child)?;
}
write!(f, "{{% endset %}}")
}
}
}
}
#[derive(Debug, Eq, PartialEq, Clone)]
pub enum TagAttribute {
HtmlAttribute(HtmlAttribute),
TwigComment(TwigComment),
TwigStructure(TwigStructure<TagAttribute>),
}
impl Display for TagAttribute {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
TagAttribute::HtmlAttribute(a) => {
write!(f, "{}", a)
}
TagAttribute::TwigComment(c) => {
write!(f, "{}", c)
}
TagAttribute::TwigStructure(s) => {
write!(f, "{}", s)
}
}
}
}
#[derive(Debug, Eq, PartialEq, Clone, Default)]
pub struct HtmlAttribute {
pub name: String,
pub value: Option<String>,
}
impl HtmlAttribute {
pub fn new(name: String, value: Option<String>) -> Self {
Self { name, value }
}
}
impl Display for HtmlAttribute {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
if let Some(v) = &self.value {
write!(f, r#"{}="{}""#, self.name, v)
} else {
write!(f, "{}", self.name)
}
}
}
#[derive(Debug, Eq, PartialEq, Clone, Default)]
pub struct Tag {
pub name: String,
pub self_closed: bool,
pub attributes: Vec<TagAttribute>,
pub children: Vec<SyntaxNode>,
}
impl Tag {
pub fn new(
name: String,
self_closed: bool,
attributes: Vec<TagAttribute>,
children: Vec<SyntaxNode>,
) -> Self {
Self {
name,
self_closed,
attributes,
children,
}
}
}
#[derive(Debug, Eq, PartialEq, Clone, Default)]
pub struct Plain {
pub plain: String,
}
impl Plain {
pub fn new(plain: String) -> Self {
Self { plain }
}
}
#[derive(Debug, Eq, PartialEq, Clone, Default)]
pub struct HtmlComment {
pub content: String,
}
impl HtmlComment {
pub fn new(content: String) -> Self {
Self { content }
}
}
#[derive(Debug, Eq, PartialEq, Clone, Default)]
pub struct OutputExpression {
pub content: String,
}
impl OutputExpression {
pub fn new(content: String) -> Self {
Self { content }
}
}
#[derive(Debug, Eq, PartialEq, Clone, Default)]
pub struct TwigComment {
pub content: String,
}
impl TwigComment {
pub fn new(content: String) -> Self {
Self { content }
}
}
impl Display for TwigComment {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{{# {} #}}", self.content)
}
}
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct TwigBlock<C> {
pub name: String,
pub children: Vec<C>,
}
impl<C> Default for TwigBlock<C> {
fn default() -> Self {
Self {
name: "".to_string(),
children: vec![],
}
}
}
impl<C> TwigBlock<C> {
pub fn new(name: String, children: Vec<C>) -> Self {
Self { name, children }
}
}
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct TwigFor<C> {
pub expression: String,
pub children: Vec<C>,
}
impl<C> Default for TwigFor<C> {
fn default() -> Self {
Self {
expression: "".to_string(),
children: vec![],
}
}
}
impl<C> TwigFor<C> {
pub fn new(expression: String, children: Vec<C>) -> Self {
Self {
expression,
children,
}
}
}
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct TwigIf<C> {
pub if_arms: Vec<TwigIfArm<C>>,
}
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct TwigIfArm<C> {
pub expression: Option<String>,
pub children: Vec<C>,
}
impl<C> Default for TwigIfArm<C> {
fn default() -> Self {
Self {
expression: None,
children: vec![],
}
}
}
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct TwigApply<C> {
pub expression: String,
pub children: Vec<C>,
}
impl<C> Default for TwigApply<C> {
fn default() -> Self {
Self {
expression: "".to_string(),
children: vec![],
}
}
}
impl<C> TwigApply<C> {
pub fn new(expression: String, children: Vec<C>) -> Self {
Self {
expression,
children,
}
}
}
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct TwigSetCapture<C> {
pub name: String,
pub children: Vec<C>,
}
impl<C> Default for TwigSetCapture<C> {
fn default() -> Self {
Self {
name: "".to_string(),
children: vec![],
}
}
}
impl<C> TwigSetCapture<C> {
pub fn new(name: String, children: Vec<C>) -> Self {
Self { name, children }
}
}