Remove support for deprecated _parent field

The support for the magic `_parent` field is deprecated since v0.8.0
or issue #180. It's bothersome to keep this feature alive, when no-one
should be using it for 3 years.
This commit is contained in:
René Kijewski 2022-07-20 15:38:30 +02:00 committed by Dirkjan Ochtman
parent bd8d2f334e
commit 16a37f4097
3 changed files with 41 additions and 52 deletions

View File

@ -293,11 +293,6 @@ impl<'a> Generator<'a> {
// Takes a Context and generates the relevant implementations. // Takes a Context and generates the relevant implementations.
fn build(mut self, ctx: &'a Context<'_>) -> Result<String, CompileError> { fn build(mut self, ctx: &'a Context<'_>) -> Result<String, CompileError> {
let mut buf = Buffer::new(0); let mut buf = Buffer::new(0);
if !ctx.blocks.is_empty() {
if let Some(parent) = self.input.parent {
self.deref_to_parent(&mut buf, parent)?;
}
};
self.impl_template(ctx, &mut buf)?; self.impl_template(ctx, &mut buf)?;
self.impl_display(&mut buf)?; self.impl_display(&mut buf)?;
@ -378,24 +373,6 @@ impl<'a> Generator<'a> {
Ok(()) Ok(())
} }
// Implement `Deref<Parent>` for an inheriting context struct.
fn deref_to_parent(
&mut self,
buf: &mut Buffer,
parent_type: &syn::Type,
) -> Result<(), CompileError> {
self.write_header(buf, "::std::ops::Deref", None)?;
buf.writeln(&format!(
"type Target = {};",
parent_type.into_token_stream()
))?;
buf.writeln("#[inline]")?;
buf.writeln("fn deref(&self) -> &Self::Target {")?;
buf.writeln("&self._parent")?;
buf.writeln("}")?;
buf.writeln("}")
}
// Implement `Display` for the given context struct. // Implement `Display` for the given context struct.
fn impl_display(&mut self, buf: &mut Buffer) -> Result<(), CompileError> { fn impl_display(&mut self, buf: &mut Buffer) -> Result<(), CompileError> {
self.write_header(buf, "::std::fmt::Display", None)?; self.write_header(buf, "::std::fmt::Display", None)?;

View File

@ -16,15 +16,13 @@ pub(crate) struct TemplateInput<'a> {
pub(crate) escaper: &'a str, pub(crate) escaper: &'a str,
pub(crate) ext: Option<String>, pub(crate) ext: Option<String>,
pub(crate) mime_type: String, pub(crate) mime_type: String,
pub(crate) parent: Option<&'a syn::Type>,
pub(crate) path: PathBuf, pub(crate) path: PathBuf,
} }
impl TemplateInput<'_> { impl TemplateInput<'_> {
/// Extract the template metadata from the `DeriveInput` structure. This /// Extract the template metadata from the `DeriveInput` structure. This
/// mostly recovers the data for the `TemplateInput` fields from the /// mostly recovers the data for the `TemplateInput` fields from the
/// `template()` attribute list fields; it also finds the of the `_parent` /// `template()` attribute list fields.
/// field, if any.
pub(crate) fn new<'n>( pub(crate) fn new<'n>(
ast: &'n syn::DeriveInput, ast: &'n syn::DeriveInput,
config: &'n Config<'_>, config: &'n Config<'_>,
@ -51,27 +49,6 @@ impl TemplateInput<'_> {
} }
}; };
// Check to see if a `_parent` field was defined on the context
// struct, and store the type for it for use in the code generator.
let parent = match ast.data {
syn::Data::Struct(syn::DataStruct {
fields: syn::Fields::Named(ref fields),
..
}) => fields
.named
.iter()
.find(|f| f.ident.as_ref().filter(|name| *name == "_parent").is_some())
.map(|f| &f.ty),
_ => None,
};
if parent.is_some() {
eprint!(
" --> in struct {}\n = use of deprecated field '_parent'\n",
ast.ident
);
}
// Validate syntax // Validate syntax
let syntax = syntax.map_or_else( let syntax = syntax.map_or_else(
|| Ok(config.syntaxes.get(config.default_syntax).unwrap()), || Ok(config.syntaxes.get(config.default_syntax).unwrap()),
@ -117,7 +94,6 @@ impl TemplateInput<'_> {
escaper, escaper,
ext, ext,
mime_type, mime_type,
parent,
path, path,
}) })
} }

View File

@ -1,3 +1,5 @@
use std::ops::Deref;
use askama::Template; use askama::Template;
#[derive(Template)] #[derive(Template)]
@ -9,7 +11,15 @@ struct BaseTemplate<'a> {
#[derive(Template)] #[derive(Template)]
#[template(path = "child.html")] #[template(path = "child.html")]
struct ChildTemplate<'a> { struct ChildTemplate<'a> {
_parent: BaseTemplate<'a>, _parent: &'a BaseTemplate<'a>,
}
impl<'a> Deref for ChildTemplate<'a> {
type Target = BaseTemplate<'a>;
fn deref(&self) -> &Self::Target {
self._parent
}
} }
#[test] #[test]
@ -21,7 +31,7 @@ fn test_use_base_directly() {
#[test] #[test]
fn test_simple_extends() { fn test_simple_extends() {
let t = ChildTemplate { let t = ChildTemplate {
_parent: BaseTemplate { title: "Bar" }, _parent: &BaseTemplate { title: "Bar" },
}; };
assert_eq!( assert_eq!(
t.render().unwrap(), t.render().unwrap(),
@ -43,6 +53,7 @@ fn test_empty_child() {
pub mod parent { pub mod parent {
use askama::Template; use askama::Template;
#[derive(Template)] #[derive(Template)]
#[template(path = "base.html")] #[template(path = "base.html")]
pub struct BaseTemplate<'a> { pub struct BaseTemplate<'a> {
@ -53,17 +64,26 @@ pub mod parent {
pub mod child { pub mod child {
use super::parent::*; use super::parent::*;
use askama::Template; use askama::Template;
#[derive(Template)] #[derive(Template)]
#[template(path = "child.html")] #[template(path = "child.html")]
pub struct ChildTemplate<'a> { pub struct ChildTemplate<'a> {
pub _parent: BaseTemplate<'a>, pub _parent: &'a BaseTemplate<'a>,
}
impl<'a> std::ops::Deref for ChildTemplate<'a> {
type Target = BaseTemplate<'a>;
fn deref(&self) -> &Self::Target {
self._parent
}
} }
} }
#[test] #[test]
fn test_different_module() { fn test_different_module() {
let t = child::ChildTemplate { let t = child::ChildTemplate {
_parent: parent::BaseTemplate { title: "a" }, _parent: &parent::BaseTemplate { title: "a" },
}; };
assert_eq!( assert_eq!(
t.render().unwrap(), t.render().unwrap(),
@ -81,6 +101,14 @@ struct NestedChildTemplate {
_parent: NestedBaseTemplate, _parent: NestedBaseTemplate,
} }
impl Deref for NestedChildTemplate {
type Target = NestedBaseTemplate;
fn deref(&self) -> &Self::Target {
&self._parent
}
}
#[test] #[test]
fn test_nested_blocks() { fn test_nested_blocks() {
let t = NestedChildTemplate { let t = NestedChildTemplate {
@ -109,6 +137,14 @@ struct DeepKidTemplate {
item: String, item: String,
} }
impl Deref for DeepKidTemplate {
type Target = DeepMidTemplate;
fn deref(&self) -> &Self::Target {
&self._parent
}
}
#[test] #[test]
fn test_deep() { fn test_deep() {
let t = DeepKidTemplate { let t = DeepKidTemplate {