Skip to content

Commit

Permalink
derive: fail if requested template block is missing
Browse files Browse the repository at this point in the history
  • Loading branch information
Kijewski committed Feb 8, 2025
1 parent a0e19aa commit b5b9ddd
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 10 deletions.
30 changes: 22 additions & 8 deletions rinja_derive/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub(crate) fn template_to_string(
heritage: Option<&Heritage<'_, '_>>,
tmpl_kind: TmplKind<'_>,
) -> Result<usize, CompileError> {
let generator = Generator::new(
let mut generator = Generator::new(
input,
contexts,
heritage,
Expand All @@ -36,13 +36,24 @@ pub(crate) fn template_to_string(
0,
);
let size_hint = match generator.impl_template(buf, tmpl_kind) {
Err(mut err) if err.span.is_none() => {
err.span = input.source_span;
Err(err)
Ok(size_hint) => {
if !generator.block_encountered {
if let Some((block, span)) = generator.input.block {
return Err(CompileError::no_file_info(
format_args!("block `{block}` was not contained in the template"),
Some(span),
));
}
}
size_hint
}
result => result,
}?;

Err(mut err) => {
if err.span.is_none() {
err.span = input.source_span;
}
return Err(err);
}
};
if tmpl_kind == TmplKind::Struct {
impl_everything(input.ast, buf);
}
Expand Down Expand Up @@ -84,6 +95,8 @@ struct Generator<'a, 'h> {
is_in_filter_block: usize,
/// Set of called macros we are currently in. Used to prevent (indirect) recursions.
seen_macros: Vec<(&'a Macro<'a>, Option<FileInfo<'a>>)>,
/// Will be set to true by the generator if the block in `self.input.block` was encountered.
block_encountered: bool,
}

impl<'a, 'h> Generator<'a, 'h> {
Expand All @@ -109,12 +122,13 @@ impl<'a, 'h> Generator<'a, 'h> {
},
is_in_filter_block,
seen_macros: Vec::new(),
block_encountered: false,
}
}

// Implement `Template` for the given context struct.
fn impl_template(
mut self,
&mut self,
buf: &mut Buffer,
tmpl_kind: TmplKind<'a>,
) -> Result<usize, CompileError> {
Expand Down
8 changes: 6 additions & 2 deletions rinja_derive/src/generator/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ impl<'a> Generator<'a, '_> {
);
child.buf_writable = buf_writable;
let res = callback(&mut child);
self.block_encountered |= child.block_encountered;
Generator {
locals: self.locals,
buf_writable: self.buf_writable,
Expand Down Expand Up @@ -1013,8 +1014,11 @@ impl<'a> Generator<'a, '_> {

self.write_buf_writable(ctx, buf)?;

let block_fragment_write =
self.input.block.map(|(block, _)| block) == name && self.buf_writable.discard;
let is_input_block = self.input.block.map(|(block, _)| block) == name;
if is_input_block {
self.block_encountered = true;
}
let block_fragment_write = is_input_block && self.buf_writable.discard;
// Allow writing to the buffer if we're in the block fragment
if block_fragment_write {
self.buf_writable.discard = false;
Expand Down
1 change: 1 addition & 0 deletions testing/templates/no-block-with-base-template.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% extends "no-block-with-include-times-2.txt" %}
2 changes: 2 additions & 0 deletions testing/templates/no-block-with-include-times-2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{% block also_also_not_a %}{% endblock %}
{% include "no-block-with-include.txt" %}
2 changes: 2 additions & 0 deletions testing/templates/no-block-with-include.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{% block also_not_a %}{% endblock %}
{% include "no-block.txt" %}
1 change: 1 addition & 0 deletions testing/templates/no-block.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{% block not_a %}{% endblock %}
28 changes: 28 additions & 0 deletions testing/tests/ui/no-block.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use rinja::Template;

#[derive(Template)]
#[template(
ext = "txt",
source = "{% block not_a %}{% endblock %}",
block = "a"
)]
struct SourceTemplate;

#[derive(Template)]
#[template(path = "no-block.txt", block = "a")]
struct PathTemplate;

#[derive(Template)]
#[template(path = "no-block-with-include.txt", block = "a")]
struct NoBlockWithInclude;

#[derive(Template)]
#[template(path = "no-block-with-include-times-2.txt", block = "a")]
struct NoBlockWithIncludeTimes2;

#[derive(Template)]
#[template(path = "no-block-with-base-template.txt", block = "a")]
struct NoBlockWithBaseTemplate;

fn main() {
}
29 changes: 29 additions & 0 deletions testing/tests/ui/no-block.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
error: cannot find block `a`
--> tests/ui/no-block.rs:7:13
|
7 | block = "a"
| ^^^

error: cannot find block `a`
--> tests/ui/no-block.rs:12:43
|
12 | #[template(path = "no-block.txt", block = "a")]
| ^^^

error: cannot find block `a`
--> tests/ui/no-block.rs:16:56
|
16 | #[template(path = "no-block-with-include.txt", block = "a")]
| ^^^

error: cannot find block `a`
--> tests/ui/no-block.rs:20:64
|
20 | #[template(path = "no-block-with-include-times-2.txt", block = "a")]
| ^^^

error: cannot find block `a`
--> tests/ui/no-block.rs:24:62
|
24 | #[template(path = "no-block-with-base-template.txt", block = "a")]
| ^^^

0 comments on commit b5b9ddd

Please sign in to comment.