Skip to content

Commit

Permalink
Extract askama_parser from askama_derive
Browse files Browse the repository at this point in the history
  • Loading branch information
couchand committed Feb 28, 2023
1 parent c9613ff commit c58643c
Show file tree
Hide file tree
Showing 12 changed files with 223 additions and 173 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ members = [
"askama_derive",
"askama_escape",
"askama_mendes",
"askama_parser",
"askama_rocket",
"askama_tide",
"askama_warp",
Expand Down
6 changes: 2 additions & 4 deletions askama_derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ rust-version = "1.58"
proc-macro = true

[features]
config = ["serde", "basic-toml"]
config = ["askama_parser/config"]
humansize = []
markdown = []
urlencode = []
Expand All @@ -31,11 +31,9 @@ with-tide = []
with-warp = []

[dependencies]
askama_parser = { version = "0.1.0", path = "../askama_parser" }
mime = "0.3"
mime_guess = "2"
nom = "7"
proc-macro2 = "1"
quote = "1"
serde = { version = "1.0", optional = true, features = ["derive"] }
syn = "1"
basic-toml = { version = "0.1.1", optional = true }
22 changes: 12 additions & 10 deletions askama_derive/src/generator.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use crate::config::{get_template_source, read_config_file, Config, WhitespaceHandling};
use crate::heritage::{Context, Heritage};
use crate::input::{Print, Source, TemplateInput};
use crate::parser::{parse, Cond, CondTest, Expr, Loop, Node, Target, When, Whitespace, Ws};
use crate::CompileError;

use askama_parser::config::{get_template_source, Config, WhitespaceHandling};
use askama_parser::expr::Expr;
use askama_parser::node::{Cond, CondTest, Loop, Node, Target, When, Whitespace, Ws};
use askama_parser::{parse, CompileError};

use proc_macro::TokenStream;
use proc_macro2::Span;
use quote::{quote, ToTokens};

use std::collections::hash_map::{Entry, HashMap};
Expand All @@ -16,7 +19,9 @@ pub(crate) fn derive_template(input: TokenStream) -> TokenStream {
let ast: syn::DeriveInput = syn::parse(input).unwrap();
match build_template(&ast) {
Ok(source) => source.parse().unwrap(),
Err(e) => e.into_compile_error(),
Err(e) => syn::Error::new(Span::call_site(), e.msg())
.to_compile_error()
.into(),
}
}

Expand All @@ -29,8 +34,7 @@ pub(crate) fn derive_template(input: TokenStream) -> TokenStream {
/// value as passed to the `template()` attribute.
fn build_template(ast: &syn::DeriveInput) -> Result<String, CompileError> {
let template_args = TemplateArgs::new(ast)?;
let config_toml = read_config_file(template_args.config_path.as_deref())?;
let config = Config::new(&config_toml)?;
let config = Config::from_file(template_args.config_path.as_deref())?;
let input = TemplateInput::new(ast, &config, template_args)?;
let source: String = match input.source {
Source::Source(ref s) => s.clone(),
Expand Down Expand Up @@ -66,7 +70,7 @@ fn build_template(ast: &syn::DeriveInput) -> Result<String, CompileError> {
&contexts,
heritage.as_ref(),
MapChain::new(),
config.whitespace,
config.whitespace(),
)
.build(&contexts[input.path.as_path()])?;
if input.print == Print::Code || input.print == Print::All {
Expand Down Expand Up @@ -1448,9 +1452,7 @@ impl<'a> Generator<'a> {
Some(name) => self
.input
.config
.escapers
.iter()
.find_map(|(escapers, escaper)| escapers.contains(name).then_some(escaper))
.find_escaper(name)
.ok_or_else(|| CompileError::from("invalid escaper for escape filter"))?,
None => self.input.escaper,
};
Expand Down
8 changes: 4 additions & 4 deletions askama_derive/src/heritage.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::collections::HashMap;
use std::path::{Path, PathBuf};

use crate::config::Config;
use crate::parser::{Loop, Macro, Node};
use crate::CompileError;
use askama_parser::config::Config;
use askama_parser::node::{Loop, Macro, Node};
use askama_parser::CompileError;

pub(crate) struct Heritage<'a> {
pub(crate) root: &'a Context<'a>,
Expand Down Expand Up @@ -44,7 +44,7 @@ pub(crate) struct Context<'a> {

impl Context<'_> {
pub(crate) fn new<'n>(
config: &Config<'_>,
config: &Config,
path: &Path,
nodes: &'n [Node<'n>],
) -> Result<Context<'n>, CompileError> {
Expand Down
26 changes: 9 additions & 17 deletions askama_derive/src/input.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::config::{Config, Syntax};
use crate::generator::TemplateArgs;
use crate::CompileError;

use askama_parser::config::{Config, Syntax};
use askama_parser::CompileError;

use std::path::{Path, PathBuf};
use std::str::FromStr;
Expand All @@ -9,8 +10,8 @@ use mime::Mime;

pub(crate) struct TemplateInput<'a> {
pub(crate) ast: &'a syn::DeriveInput,
pub(crate) config: &'a Config<'a>,
pub(crate) syntax: &'a Syntax<'a>,
pub(crate) config: &'a Config,
pub(crate) syntax: &'a Syntax,
pub(crate) source: Source,
pub(crate) print: Print,
pub(crate) escaper: &'a str,
Expand All @@ -25,7 +26,7 @@ impl TemplateInput<'_> {
/// `template()` attribute list fields.
pub(crate) fn new<'n>(
ast: &'n syn::DeriveInput,
config: &'n Config<'_>,
config: &'n Config,
args: TemplateArgs,
) -> Result<TemplateInput<'n>, CompileError> {
let TemplateArgs {
Expand All @@ -51,11 +52,10 @@ impl TemplateInput<'_> {

// Validate syntax
let syntax = syntax.map_or_else(
|| Ok(config.syntaxes.get(config.default_syntax).unwrap()),
|| Ok(config.default_syntax()),
|s| {
config
.syntaxes
.get(&s)
.find_syntax(&s)
.ok_or_else(|| CompileError::from(format!("attribute syntax {s} not exist")))
},
)?;
Expand All @@ -69,15 +69,7 @@ impl TemplateInput<'_> {
.to_string()
});

let mut escaper = None;
for (extensions, path) in &config.escapers {
if extensions.contains(&escaping) {
escaper = Some(path);
break;
}
}

let escaper = escaper.ok_or_else(|| {
let escaper = config.find_escaper(&escaping).ok_or_else(|| {
CompileError::from(format!("no escaper defined for extension '{escaping}'"))
})?;

Expand Down
50 changes: 0 additions & 50 deletions askama_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,67 +2,17 @@
#![deny(elided_lifetimes_in_paths)]
#![deny(unreachable_pub)]

use std::borrow::Cow;
use std::fmt;

use proc_macro::TokenStream;
use proc_macro2::Span;

mod config;
mod generator;
mod heritage;
mod input;
mod parser;

#[proc_macro_derive(Template, attributes(template))]
pub fn derive_template(input: TokenStream) -> TokenStream {
generator::derive_template(input)
}

#[derive(Debug, Clone)]
struct CompileError {
msg: Cow<'static, str>,
span: Span,
}

impl CompileError {
fn new<S: Into<Cow<'static, str>>>(s: S, span: Span) -> Self {
Self {
msg: s.into(),
span,
}
}

fn into_compile_error(self) -> TokenStream {
syn::Error::new(self.span, self.msg)
.to_compile_error()
.into()
}
}

impl std::error::Error for CompileError {}

impl fmt::Display for CompileError {
#[inline]
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt.write_str(&self.msg)
}
}

impl From<&'static str> for CompileError {
#[inline]
fn from(s: &'static str) -> Self {
Self::new(s, Span::call_site())
}
}

impl From<String> for CompileError {
#[inline]
fn from(s: String) -> Self {
Self::new(s, Span::call_site())
}
}

// This is used by the code generator to decide whether a named filter is part of
// Askama or should refer to a local `filters` module. It should contain all the
// filters shipped with Askama, even the optional ones (since optional inclusion
Expand Down
19 changes: 19 additions & 0 deletions askama_parser/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "askama_parser"
version = "0.1.0"
description = "Askama template syntax parser"
homepage = "https://github.com/djc/askama"
repository = "https://github.com/djc/askama"
license = "MIT OR Apache-2.0"
workspace = ".."
readme = "../README.md"
edition = "2021"
rust-version = "1.58"

[features]
config = ["serde", "basic-toml"]

[dependencies]
nom = "7"
serde = { version = "1.0", optional = true, features = ["derive"] }
basic-toml = { version = "0.1.1", optional = true }
Loading

0 comments on commit c58643c

Please sign in to comment.