mirror of
				https://github.com/askama-rs/askama.git
				synced 2025-11-04 07:23:15 +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