mirror of
https://github.com/askama-rs/askama.git
synced 2025-11-05 16:03:12 +00:00
Extract askama_parser crate
This commit is contained in:
parent
bdb6c0b89d
commit
e40e93796f
@ -7,6 +7,7 @@ members = [
|
|||||||
"askama_derive",
|
"askama_derive",
|
||||||
"askama_escape",
|
"askama_escape",
|
||||||
"askama_mendes",
|
"askama_mendes",
|
||||||
|
"askama_parser",
|
||||||
"askama_rocket",
|
"askama_rocket",
|
||||||
"askama_tide",
|
"askama_tide",
|
||||||
"askama_warp",
|
"askama_warp",
|
||||||
@ -18,5 +19,6 @@ default-members = [
|
|||||||
"askama",
|
"askama",
|
||||||
"askama_derive",
|
"askama_derive",
|
||||||
"askama_escape",
|
"askama_escape",
|
||||||
|
"askama_parser",
|
||||||
"testing",
|
"testing",
|
||||||
]
|
]
|
||||||
|
|||||||
@ -31,9 +31,9 @@ with-tide = []
|
|||||||
with-warp = []
|
with-warp = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
parser = { package = "askama_parser", version = "0.1", path = "../askama_parser" }
|
||||||
mime = "0.3"
|
mime = "0.3"
|
||||||
mime_guess = "2"
|
mime_guess = "2"
|
||||||
nom = "7"
|
|
||||||
proc-macro2 = "1"
|
proc-macro2 = "1"
|
||||||
quote = "1"
|
quote = "1"
|
||||||
serde = { version = "1.0", optional = true, features = ["derive"] }
|
serde = { version = "1.0", optional = true, features = ["derive"] }
|
||||||
|
|||||||
@ -5,8 +5,8 @@ use std::{env, fs};
|
|||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::parser::{Syntax, Whitespace};
|
|
||||||
use crate::CompileError;
|
use crate::CompileError;
|
||||||
|
use parser::{Syntax, Whitespace};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct Config<'a> {
|
pub(crate) struct Config<'a> {
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
use crate::config::{get_template_source, read_config_file, Config, WhitespaceHandling};
|
use crate::config::{get_template_source, read_config_file, Config, WhitespaceHandling};
|
||||||
use crate::heritage::{Context, Heritage};
|
use crate::heritage::{Context, Heritage};
|
||||||
use crate::input::{Print, Source, TemplateInput};
|
use crate::input::{Print, Source, TemplateInput};
|
||||||
use crate::parser::{Cond, CondTest, Expr, Loop, Node, Parsed, Target, When, Whitespace, Ws};
|
|
||||||
use crate::CompileError;
|
use crate::CompileError;
|
||||||
|
use parser::{Cond, CondTest, Expr, Loop, Node, Parsed, Target, When, Whitespace, Ws};
|
||||||
|
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use quote::{quote, ToTokens};
|
use quote::{quote, ToTokens};
|
||||||
|
|||||||
@ -2,8 +2,8 @@ use std::collections::HashMap;
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::parser::{Loop, Macro, Node};
|
|
||||||
use crate::CompileError;
|
use crate::CompileError;
|
||||||
|
use parser::{Loop, Macro, Node};
|
||||||
|
|
||||||
pub(crate) struct Heritage<'a> {
|
pub(crate) struct Heritage<'a> {
|
||||||
pub(crate) root: &'a Context<'a>,
|
pub(crate) root: &'a Context<'a>,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::generator::TemplateArgs;
|
use crate::generator::TemplateArgs;
|
||||||
use crate::parser::Syntax;
|
|
||||||
use crate::CompileError;
|
use crate::CompileError;
|
||||||
|
use parser::Syntax;
|
||||||
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|||||||
@ -7,12 +7,12 @@ use std::fmt;
|
|||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use proc_macro2::Span;
|
use proc_macro2::Span;
|
||||||
|
|
||||||
|
use parser::ParseError;
|
||||||
|
|
||||||
mod config;
|
mod config;
|
||||||
mod generator;
|
mod generator;
|
||||||
mod heritage;
|
mod heritage;
|
||||||
mod input;
|
mod input;
|
||||||
mod parser;
|
|
||||||
use parser::ParseError;
|
|
||||||
|
|
||||||
#[proc_macro_derive(Template, attributes(template))]
|
#[proc_macro_derive(Template, attributes(template))]
|
||||||
pub fn derive_template(input: TokenStream) -> TokenStream {
|
pub fn derive_template(input: TokenStream) -> TokenStream {
|
||||||
|
|||||||
17
askama_parser/Cargo.toml
Normal file
17
askama_parser/Cargo.toml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
[package]
|
||||||
|
name = "askama_parser"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "Parser for Askama templates"
|
||||||
|
documentation = "https://docs.rs/askama"
|
||||||
|
keywords = ["markup", "template", "jinja2", "html"]
|
||||||
|
categories = ["template-engine"]
|
||||||
|
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"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
nom = { version = "7", default-features = false, features = ["alloc"] }
|
||||||
@ -14,7 +14,7 @@ use super::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub(crate) enum Expr<'a> {
|
pub enum Expr<'a> {
|
||||||
BoolLit(&'a str),
|
BoolLit(&'a str),
|
||||||
NumLit(&'a str),
|
NumLit(&'a str),
|
||||||
StrLit(&'a str),
|
StrLit(&'a str),
|
||||||
@ -1,3 +1,6 @@
|
|||||||
|
#![deny(unreachable_pub)]
|
||||||
|
#![deny(elided_lifetimes_in_paths)]
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::{fmt, str};
|
use std::{fmt, str};
|
||||||
|
|
||||||
@ -11,8 +14,8 @@ use nom::multi::separated_list1;
|
|||||||
use nom::sequence::{delimited, pair, tuple};
|
use nom::sequence::{delimited, pair, tuple};
|
||||||
use nom::{error_position, AsChar, IResult, InputTakeAtPosition};
|
use nom::{error_position, AsChar, IResult, InputTakeAtPosition};
|
||||||
|
|
||||||
pub(crate) use self::expr::Expr;
|
pub use self::expr::Expr;
|
||||||
pub(crate) use self::node::{Cond, CondTest, Loop, Macro, Node, Target, When, Whitespace, Ws};
|
pub use self::node::{Cond, CondTest, Loop, Macro, Node, Target, When, Whitespace, Ws};
|
||||||
|
|
||||||
mod expr;
|
mod expr;
|
||||||
mod node;
|
mod node;
|
||||||
@ -61,14 +64,14 @@ mod _parsed {
|
|||||||
|
|
||||||
use super::{parse, Node, ParseError, Syntax};
|
use super::{parse, Node, ParseError, Syntax};
|
||||||
|
|
||||||
pub(crate) struct Parsed {
|
pub struct Parsed {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
source: String,
|
source: String,
|
||||||
nodes: Vec<Node<'static>>,
|
nodes: Vec<Node<'static>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parsed {
|
impl Parsed {
|
||||||
pub(crate) fn new(source: String, syntax: &Syntax<'_>) -> Result<Self, ParseError> {
|
pub fn new(source: String, syntax: &Syntax<'_>) -> Result<Self, ParseError> {
|
||||||
// Self-referential borrowing: `self` will keep the source alive as `String`,
|
// Self-referential borrowing: `self` will keep the source alive as `String`,
|
||||||
// internally we will transmute it to `&'static str` to satisfy the compiler.
|
// internally we will transmute it to `&'static str` to satisfy the compiler.
|
||||||
// However, we only expose the nodes with a lifetime limited to `self`.
|
// However, we only expose the nodes with a lifetime limited to `self`.
|
||||||
@ -82,15 +85,15 @@ mod _parsed {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The return value's lifetime must be limited to `self` to uphold the unsafe invariant.
|
// The return value's lifetime must be limited to `self` to uphold the unsafe invariant.
|
||||||
pub(crate) fn nodes(&self) -> &[Node<'_>] {
|
pub fn nodes(&self) -> &[Node<'_>] {
|
||||||
&self.nodes
|
&self.nodes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) use _parsed::Parsed;
|
pub use _parsed::Parsed;
|
||||||
|
|
||||||
pub(crate) fn parse<'a>(src: &'a str, syntax: &Syntax<'_>) -> Result<Vec<Node<'a>>, ParseError> {
|
pub fn parse<'a>(src: &'a str, syntax: &Syntax<'_>) -> Result<Vec<Node<'a>>, ParseError> {
|
||||||
match Node::parse(src, &State::new(syntax)) {
|
match Node::parse(src, &State::new(syntax)) {
|
||||||
Ok((left, res)) => {
|
Ok((left, res)) => {
|
||||||
if !left.is_empty() {
|
if !left.is_empty() {
|
||||||
@ -128,7 +131,7 @@ pub(crate) fn parse<'a>(src: &'a str, syntax: &Syntax<'_>) -> Result<Vec<Node<'a
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub(crate) struct ParseError(String);
|
pub struct ParseError(String);
|
||||||
|
|
||||||
impl std::error::Error for ParseError {}
|
impl std::error::Error for ParseError {}
|
||||||
|
|
||||||
@ -358,13 +361,13 @@ fn tag_expr_end<'a>(i: &'a str, s: &State<'_>) -> IResult<&'a str, &'a str> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct Syntax<'a> {
|
pub struct Syntax<'a> {
|
||||||
pub(crate) block_start: &'a str,
|
pub block_start: &'a str,
|
||||||
pub(crate) block_end: &'a str,
|
pub block_end: &'a str,
|
||||||
pub(crate) expr_start: &'a str,
|
pub expr_start: &'a str,
|
||||||
pub(crate) expr_end: &'a str,
|
pub expr_end: &'a str,
|
||||||
pub(crate) comment_start: &'a str,
|
pub comment_start: &'a str,
|
||||||
pub(crate) comment_end: &'a str,
|
pub comment_end: &'a str,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Syntax<'static> {
|
impl Default for Syntax<'static> {
|
||||||
@ -16,7 +16,7 @@ use super::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub(crate) enum Node<'a> {
|
pub enum Node<'a> {
|
||||||
Lit(&'a str, &'a str, &'a str),
|
Lit(&'a str, &'a str, &'a str),
|
||||||
Comment(Ws),
|
Comment(Ws),
|
||||||
Expr(Ws, Expr<'a>),
|
Expr(Ws, Expr<'a>),
|
||||||
@ -37,7 +37,7 @@ pub(crate) enum Node<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub(crate) enum Target<'a> {
|
pub enum Target<'a> {
|
||||||
Name(&'a str),
|
Name(&'a str),
|
||||||
Tuple(Vec<&'a str>, Vec<Target<'a>>),
|
Tuple(Vec<&'a str>, Vec<Target<'a>>),
|
||||||
Struct(Vec<&'a str>, Vec<(&'a str, Target<'a>)>),
|
Struct(Vec<&'a str>, Vec<(&'a str, Target<'a>)>),
|
||||||
@ -49,46 +49,46 @@ pub(crate) enum Target<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
pub(crate) enum Whitespace {
|
pub enum Whitespace {
|
||||||
Preserve,
|
Preserve,
|
||||||
Suppress,
|
Suppress,
|
||||||
Minimize,
|
Minimize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub(crate) struct Loop<'a> {
|
pub struct Loop<'a> {
|
||||||
pub(crate) ws1: Ws,
|
pub ws1: Ws,
|
||||||
pub(crate) var: Target<'a>,
|
pub var: Target<'a>,
|
||||||
pub(crate) iter: Expr<'a>,
|
pub iter: Expr<'a>,
|
||||||
pub(crate) cond: Option<Expr<'a>>,
|
pub cond: Option<Expr<'a>>,
|
||||||
pub(crate) body: Vec<Node<'a>>,
|
pub body: Vec<Node<'a>>,
|
||||||
pub(crate) ws2: Ws,
|
pub ws2: Ws,
|
||||||
pub(crate) else_block: Vec<Node<'a>>,
|
pub else_block: Vec<Node<'a>>,
|
||||||
pub(crate) ws3: Ws,
|
pub ws3: Ws,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) type When<'a> = (Ws, Target<'a>, Vec<Node<'a>>);
|
pub type When<'a> = (Ws, Target<'a>, Vec<Node<'a>>);
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub(crate) struct Macro<'a> {
|
pub struct Macro<'a> {
|
||||||
pub(crate) ws1: Ws,
|
pub ws1: Ws,
|
||||||
pub(crate) args: Vec<&'a str>,
|
pub args: Vec<&'a str>,
|
||||||
pub(crate) nodes: Vec<Node<'a>>,
|
pub nodes: Vec<Node<'a>>,
|
||||||
pub(crate) ws2: Ws,
|
pub ws2: Ws,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// First field is "minus/plus sign was used on the left part of the item".
|
/// First field is "minus/plus sign was used on the left part of the item".
|
||||||
///
|
///
|
||||||
/// Second field is "minus/plus sign was used on the right part of the item".
|
/// Second field is "minus/plus sign was used on the right part of the item".
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||||
pub(crate) struct Ws(pub(crate) Option<Whitespace>, pub(crate) Option<Whitespace>);
|
pub struct Ws(pub Option<Whitespace>, pub Option<Whitespace>);
|
||||||
|
|
||||||
pub(crate) type Cond<'a> = (Ws, Option<CondTest<'a>>, Vec<Node<'a>>);
|
pub type Cond<'a> = (Ws, Option<CondTest<'a>>, Vec<Node<'a>>);
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub(crate) struct CondTest<'a> {
|
pub struct CondTest<'a> {
|
||||||
pub(crate) target: Option<Target<'a>>,
|
pub target: Option<Target<'a>>,
|
||||||
pub(crate) expr: Expr<'a>,
|
pub expr: Expr<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Node<'_> {
|
impl Node<'_> {
|
||||||
Loading…
x
Reference in New Issue
Block a user