From f6e567a78eaaa6ba67ca6958a8668dbdcaa5d8e0 Mon Sep 17 00:00:00 2001 From: Josh Date: Mon, 8 Sep 2025 21:31:45 -0500 Subject: [PATCH] use Node substructs for enum fields --- crates/djls-templates/src/ast.rs | 60 ++++++++++--------------- crates/djls-templates/src/parser.rs | 22 +++++---- crates/djls-templates/src/validation.rs | 3 +- 3 files changed, 38 insertions(+), 47 deletions(-) diff --git a/crates/djls-templates/src/ast.rs b/crates/djls-templates/src/ast.rs index 7ad4e525..44358585 100644 --- a/crates/djls-templates/src/ast.rs +++ b/crates/djls-templates/src/ast.rs @@ -3,21 +3,6 @@ use thiserror::Error; use crate::tokens::Token; -#[salsa::interned(debug)] -pub struct TagName<'db> { - pub text: String, -} - -#[salsa::interned(debug)] -pub struct VariableName<'db> { - pub text: String, -} - -#[salsa::interned(debug)] -pub struct FilterName<'db> { - pub text: String, -} - #[salsa::tracked(debug)] pub struct Ast<'db> { #[tracked] @@ -71,52 +56,53 @@ impl Default for LineOffsets { #[derive(Clone, Debug, PartialEq, Eq, salsa::Update)] pub enum Node<'db> { - Tag { - name: TagName<'db>, - bits: Vec, // Keep as strings for now, could intern later - span: Span<'db>, - }, - Comment { - content: String, // Keep as string - not repeated - span: Span<'db>, - }, - Text { - content: String, // Keep as string - not repeated - span: Span<'db>, - }, - Variable { - var: VariableName<'db>, - filters: Vec>, - span: Span<'db>, - }, + Tag(TagNode<'db>), + Comment(CommentNode<'db>), + Text(TextNode<'db>), + Variable(VariableNode<'db>), } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq, salsa::Update)] pub struct TagNode<'db> { pub name: TagName<'db>, pub bits: Vec, pub span: Span<'db>, } -#[derive(Debug, Clone)] +#[salsa::interned(debug)] +pub struct TagName<'db> { + pub text: String, +} + +#[derive(Debug, Clone, PartialEq, Eq, salsa::Update)] pub struct CommentNode<'db> { pub content: String, pub span: Span<'db>, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq, salsa::Update)] pub struct TextNode<'db> { pub content: String, pub span: Span<'db>, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq, salsa::Update)] pub struct VariableNode<'db> { pub var: VariableName<'db>, pub filters: Vec>, pub span: Span<'db>, } +#[salsa::interned(debug)] +pub struct VariableName<'db> { + pub text: String, +} + +#[salsa::interned(debug)] +pub struct FilterName<'db> { + pub text: String, +} + #[salsa::tracked(debug)] pub struct Span<'db> { #[tracked] diff --git a/crates/djls-templates/src/parser.rs b/crates/djls-templates/src/parser.rs index 542e7278..792e92ff 100644 --- a/crates/djls-templates/src/parser.rs +++ b/crates/djls-templates/src/parser.rs @@ -2,11 +2,15 @@ use thiserror::Error; use crate::ast::Ast; use crate::ast::AstError; +use crate::ast::CommentNode; use crate::ast::FilterName; use crate::ast::Node; use crate::ast::Span; use crate::ast::TagName; +use crate::ast::TagNode; +use crate::ast::TextNode; use crate::ast::VariableName; +use crate::ast::VariableNode; use crate::db::Db as TemplateDb; use crate::lexer::LexerError; use crate::tokens::Token; @@ -95,10 +99,10 @@ impl<'db> Parser<'db> { let token = self.peek_previous()?; - Ok(Node::Comment { + Ok(Node::Comment(CommentNode { content: token.content(), span: Span::from_token(self.db, &token), - }) + })) } pub fn parse_django_block(&mut self) -> Result, ParserError> { @@ -114,7 +118,7 @@ impl<'db> Parser<'db> { let bits = args.into_iter().skip(1).collect(); let span = Span::from_token(self.db, &token); - Ok(Node::Tag { name, bits, span }) + Ok(Node::Tag(TagNode { name, bits, span })) } fn parse_django_variable(&mut self) -> Result, ParserError> { @@ -135,7 +139,7 @@ impl<'db> Parser<'db> { .collect(); let span = Span::from_token(self.db, &token); - Ok(Node::Variable { var, filters, span }) + Ok(Node::Variable(VariableNode { var, filters, span })) } fn parse_text(&mut self) -> Result, ParserError> { @@ -173,7 +177,7 @@ impl<'db> Parser<'db> { let length = u32::try_from(content.len()).expect("Content length should fit in u32"); let span = Span::new(self.db, start + offset, length); - Ok(Node::Text { content, span }) + Ok(Node::Text(TextNode { content, span })) } fn peek(&self) -> Result { @@ -397,20 +401,20 @@ mod tests { impl TestNode { fn from_node(node: &Node<'_>, db: &dyn crate::db::Db) -> Self { match node { - Node::Tag { name, bits, span } => TestNode::Tag { + Node::Tag(TagNode { name, bits, span }) => TestNode::Tag { name: name.text(db).to_string(), bits: bits.clone(), span: (span.start(db), span.length(db)), }, - Node::Comment { content, span } => TestNode::Comment { + Node::Comment(CommentNode { content, span }) => TestNode::Comment { content: content.clone(), span: (span.start(db), span.length(db)), }, - Node::Text { content, span } => TestNode::Text { + Node::Text(TextNode { content, span }) => TestNode::Text { content: content.clone(), span: (span.start(db), span.length(db)), }, - Node::Variable { var, filters, span } => TestNode::Variable { + Node::Variable(VariableNode { var, filters, span }) => TestNode::Variable { var: var.text(db).to_string(), filters: filters.iter().map(|f| f.text(db).to_string()).collect(), span: (span.start(db), span.length(db)), diff --git a/crates/djls-templates/src/validation.rs b/crates/djls-templates/src/validation.rs index 448d6bbc..d5c3ee83 100644 --- a/crates/djls-templates/src/validation.rs +++ b/crates/djls-templates/src/validation.rs @@ -50,7 +50,8 @@ impl<'db> TagValidator<'db> { #[must_use] pub fn validate(mut self) -> Vec { while !self.is_at_end() { - if let Some(Node::Tag { name, bits, span }) = self.current_node() { + if let Some(Node::Tag(tag_node)) = self.current_node() { + let TagNode { name, bits, span } = tag_node; let name_str = name.text(self.db); let tag_specs = self.db.tag_specs();