Merge branch 'pr/104'
This commit is contained in:
commit
1c2fc83d6b
|
@ -56,6 +56,7 @@ impl Default for Parser {
|
|||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub enum TokenKind {
|
||||
NestedTemplateOnce,
|
||||
BufferedCode { escape: bool },
|
||||
Code,
|
||||
Comment,
|
||||
|
@ -161,6 +162,10 @@ impl<'a> ParseStream<'a> {
|
|||
token_kind = TokenKind::BufferedCode { escape: false };
|
||||
start += 1;
|
||||
}
|
||||
Some(b'+') => {
|
||||
token_kind = TokenKind::NestedTemplateOnce;
|
||||
start += 1;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
@ -402,6 +407,33 @@ mod tests {
|
|||
use super::*;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[test]
|
||||
fn nested_render_once() {
|
||||
let src = r#"outer <%+ inner|upper %> outer"#;
|
||||
let parser = Parser::default();
|
||||
let tokens = parser.parse(src).into_vec().unwrap();
|
||||
assert_eq!(
|
||||
&tokens,
|
||||
&[
|
||||
Token {
|
||||
content: "outer ",
|
||||
offset: 0,
|
||||
kind: TokenKind::Text,
|
||||
},
|
||||
Token {
|
||||
content: "inner|upper",
|
||||
offset: 10,
|
||||
kind: TokenKind::NestedTemplateOnce,
|
||||
},
|
||||
Token {
|
||||
content: " outer",
|
||||
offset: 24,
|
||||
kind: TokenKind::Text,
|
||||
},
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn non_ascii_delimiter() {
|
||||
let src = r##"foo <🍣# This is a comment 🍣> bar <🍣= r"🍣>" 🍣> baz <🍣🍣"##;
|
||||
|
|
|
@ -135,6 +135,15 @@ impl SourceBuilder {
|
|||
&mut self,
|
||||
token: &Token<'a>,
|
||||
escape: bool,
|
||||
) -> Result<(), Error> {
|
||||
self.write_buffered_code_with_suffix(token, escape, "")
|
||||
}
|
||||
|
||||
fn write_buffered_code_with_suffix<'a>(
|
||||
&mut self,
|
||||
token: &Token<'a>,
|
||||
escape: bool,
|
||||
suffix: &str,
|
||||
) -> Result<(), Error> {
|
||||
// parse and split off filter
|
||||
let code_block = syn::parse_str::<CodeBlock>(token.as_str()).map_err(|e| {
|
||||
|
@ -154,7 +163,7 @@ impl SourceBuilder {
|
|||
self.source.push_str("!(__sf_buf, ");
|
||||
|
||||
if let Some(filter) = code_block.filter {
|
||||
let expr_str = code_block.expr.into_token_stream().to_string();
|
||||
let expr_str = format!("{}{}", code_block.expr.into_token_stream(), suffix);
|
||||
let (name, extra_args) = match filter {
|
||||
Filter::Ident(i) => (i.to_string(), None),
|
||||
Filter::Call(c) => (
|
||||
|
@ -188,6 +197,7 @@ impl SourceBuilder {
|
|||
self.source.push(')');
|
||||
} else {
|
||||
self.write_token(token);
|
||||
self.source.push_str(suffix);
|
||||
}
|
||||
|
||||
self.source.push_str(");\n");
|
||||
|
@ -205,6 +215,11 @@ impl SourceBuilder {
|
|||
TokenKind::BufferedCode { escape } => {
|
||||
self.write_buffered_code(&token, escape)?
|
||||
}
|
||||
TokenKind::NestedTemplateOnce => self.write_buffered_code_with_suffix(
|
||||
&token,
|
||||
false,
|
||||
".render_once()?",
|
||||
)?,
|
||||
TokenKind::Text => {
|
||||
// concatenate repeated text token
|
||||
let offset = token.offset();
|
||||
|
@ -367,4 +382,48 @@ mod tests {
|
|||
ps.feed_tokens(token_iter.clone()).unwrap();
|
||||
Translator::new().translate(token_iter).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn translate_nested_render_once() {
|
||||
let src = r#"outer <%+ inner %> outer"#;
|
||||
let lexer = Parser::new();
|
||||
let token_iter = lexer.parse(src);
|
||||
let mut ps = SourceBuilder {
|
||||
escape: true,
|
||||
source: String::with_capacity(token_iter.original_source.len()),
|
||||
source_map: SourceMap::default(),
|
||||
};
|
||||
ps.feed_tokens(token_iter.clone()).unwrap();
|
||||
assert_eq!(
|
||||
&Translator::new()
|
||||
.translate(token_iter)
|
||||
.unwrap()
|
||||
.ast
|
||||
.into_token_stream()
|
||||
.to_string(),
|
||||
r#"{ __sf_rt :: render_text ! (__sf_buf , "outer ") ; __sf_rt :: render ! (__sf_buf , inner . render_once () ?) ; __sf_rt :: render_text ! (__sf_buf , " outer") ; }"#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn translate_nested_render_once_with_filter() {
|
||||
let src = r#"outer <%+ inner|upper %> outer"#;
|
||||
let lexer = Parser::new();
|
||||
let token_iter = lexer.parse(src);
|
||||
let mut ps = SourceBuilder {
|
||||
escape: true,
|
||||
source: String::with_capacity(token_iter.original_source.len()),
|
||||
source_map: SourceMap::default(),
|
||||
};
|
||||
ps.feed_tokens(token_iter.clone()).unwrap();
|
||||
assert_eq!(
|
||||
&Translator::new()
|
||||
.translate(token_iter)
|
||||
.unwrap()
|
||||
.ast
|
||||
.into_token_stream()
|
||||
.to_string(),
|
||||
r#"{ __sf_rt :: render_text ! (__sf_buf , "outer ") ; __sf_rt :: render ! (__sf_buf , sailfish :: runtime :: filter :: upper (& (inner . render_once () ?))) ; __sf_rt :: render_text ! (__sf_buf , " outer") ; }"#
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue