mirror of
https://github.com/askama-rs/askama.git
synced 2025-10-05 00:35:17 +00:00
Pass variables to sub-templates more reliably even if indirectly
This commit is contained in:
parent
4a17df55b5
commit
d6bf966048
@ -6,7 +6,7 @@ use core::pin::Pin;
|
|||||||
|
|
||||||
use super::MAX_LEN;
|
use super::MAX_LEN;
|
||||||
use super::escape::FastWritable;
|
use super::escape::FastWritable;
|
||||||
use crate::{Error, Result};
|
use crate::{Error, Result, Values};
|
||||||
|
|
||||||
/// Limit string length, appends '...' if truncated
|
/// Limit string length, appends '...' if truncated
|
||||||
///
|
///
|
||||||
@ -50,9 +50,13 @@ impl<S: fmt::Display> fmt::Display for TruncateFilter<S> {
|
|||||||
|
|
||||||
impl<S: FastWritable> FastWritable for TruncateFilter<S> {
|
impl<S: FastWritable> FastWritable for TruncateFilter<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
|
fn write_into<W: fmt::Write + ?Sized>(
|
||||||
|
&self,
|
||||||
|
dest: &mut W,
|
||||||
|
values: &dyn Values,
|
||||||
|
) -> crate::Result<()> {
|
||||||
self.source
|
self.source
|
||||||
.write_into(&mut TruncateWriter::new(dest, self.remaining))
|
.write_into(&mut TruncateWriter::new(dest, self.remaining), values)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,10 +444,14 @@ impl<S: fmt::Display, P: fmt::Display> fmt::Display for Pluralize<S, P> {
|
|||||||
|
|
||||||
impl<S: FastWritable, P: FastWritable> FastWritable for Pluralize<S, P> {
|
impl<S: FastWritable, P: FastWritable> FastWritable for Pluralize<S, P> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
|
fn write_into<W: fmt::Write + ?Sized>(
|
||||||
|
&self,
|
||||||
|
dest: &mut W,
|
||||||
|
values: &dyn Values,
|
||||||
|
) -> crate::Result<()> {
|
||||||
match self {
|
match self {
|
||||||
Pluralize::Singular(value) => value.write_into(dest),
|
Pluralize::Singular(value) => value.write_into(dest, values),
|
||||||
Pluralize::Plural(value) => value.write_into(dest),
|
Pluralize::Plural(value) => value.write_into(dest, values),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,8 +82,12 @@ impl<T: fmt::Display, E: Escaper> fmt::Display for EscapeDisplay<T, E> {
|
|||||||
|
|
||||||
impl<T: FastWritable, E: Escaper> FastWritable for EscapeDisplay<T, E> {
|
impl<T: FastWritable, E: Escaper> FastWritable for EscapeDisplay<T, E> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
|
fn write_into<W: fmt::Write + ?Sized>(
|
||||||
self.0.write_into(&mut EscapeWriter(dest, self.1))
|
&self,
|
||||||
|
dest: &mut W,
|
||||||
|
values: &dyn Values,
|
||||||
|
) -> crate::Result<()> {
|
||||||
|
self.0.write_into(&mut EscapeWriter(dest, self.1), values)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,12 +307,16 @@ const _: () = {
|
|||||||
// This is the fallback. The filter is not the last element of the filter chain.
|
// This is the fallback. The filter is not the last element of the filter chain.
|
||||||
impl<T: FastWritable> FastWritable for MaybeSafe<T> {
|
impl<T: FastWritable> FastWritable for MaybeSafe<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
|
fn write_into<W: fmt::Write + ?Sized>(
|
||||||
|
&self,
|
||||||
|
dest: &mut W,
|
||||||
|
values: &dyn Values,
|
||||||
|
) -> crate::Result<()> {
|
||||||
let inner = match self {
|
let inner = match self {
|
||||||
MaybeSafe::Safe(inner) => inner,
|
MaybeSafe::Safe(inner) => inner,
|
||||||
MaybeSafe::NeedsEscaping(inner) => inner,
|
MaybeSafe::NeedsEscaping(inner) => inner,
|
||||||
};
|
};
|
||||||
inner.write_into(dest)
|
inner.write_into(dest, values)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,10 +346,14 @@ const _: () = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: FastWritable + ?Sized, E: Escaper> FastWritable for Wrapped<'_, T, E> {
|
impl<T: FastWritable + ?Sized, E: Escaper> FastWritable for Wrapped<'_, T, E> {
|
||||||
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
|
fn write_into<W: fmt::Write + ?Sized>(
|
||||||
|
&self,
|
||||||
|
dest: &mut W,
|
||||||
|
values: &dyn Values,
|
||||||
|
) -> crate::Result<()> {
|
||||||
match *self {
|
match *self {
|
||||||
Wrapped::Safe(t) => t.write_into(dest),
|
Wrapped::Safe(t) => t.write_into(dest, values),
|
||||||
Wrapped::NeedsEscaping(t, e) => EscapeDisplay(t, e).write_into(dest),
|
Wrapped::NeedsEscaping(t, e) => EscapeDisplay(t, e).write_into(dest, values),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -409,8 +421,12 @@ const _: () = {
|
|||||||
// This is the fallback. The filter is not the last element of the filter chain.
|
// This is the fallback. The filter is not the last element of the filter chain.
|
||||||
impl<T: FastWritable> FastWritable for Safe<T> {
|
impl<T: FastWritable> FastWritable for Safe<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
|
fn write_into<W: fmt::Write + ?Sized>(
|
||||||
self.0.write_into(dest)
|
&self,
|
||||||
|
dest: &mut W,
|
||||||
|
values: &dyn Values,
|
||||||
|
) -> crate::Result<()> {
|
||||||
|
self.0.write_into(dest, values)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -503,15 +519,23 @@ pub trait WriteWritable {
|
|||||||
/// Types implementing this trait can be written without needing to employ an [`fmt::Formatter`].
|
/// Types implementing this trait can be written without needing to employ an [`fmt::Formatter`].
|
||||||
pub trait FastWritable {
|
pub trait FastWritable {
|
||||||
/// Used internally by askama to speed up writing some types.
|
/// Used internally by askama to speed up writing some types.
|
||||||
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()>;
|
fn write_into<W: fmt::Write + ?Sized>(
|
||||||
|
&self,
|
||||||
|
dest: &mut W,
|
||||||
|
values: &dyn Values,
|
||||||
|
) -> crate::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const _: () = {
|
const _: () = {
|
||||||
crate::impl_for_ref! {
|
crate::impl_for_ref! {
|
||||||
impl FastWritable for T {
|
impl FastWritable for T {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
|
fn write_into<W: fmt::Write + ?Sized>(
|
||||||
<T>::write_into(self, dest)
|
&self,
|
||||||
|
dest: &mut W,
|
||||||
|
values: &dyn Values,
|
||||||
|
) -> crate::Result<()> {
|
||||||
|
<T>::write_into(self, dest, values)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -522,16 +546,24 @@ const _: () = {
|
|||||||
<T as Deref>::Target: FastWritable,
|
<T as Deref>::Target: FastWritable,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
|
fn write_into<W: fmt::Write + ?Sized>(
|
||||||
self.as_ref().get_ref().write_into(dest)
|
&self,
|
||||||
|
dest: &mut W,
|
||||||
|
values: &dyn Values,
|
||||||
|
) -> crate::Result<()> {
|
||||||
|
self.as_ref().get_ref().write_into(dest, values)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
impl<T: FastWritable + alloc::borrow::ToOwned> FastWritable for alloc::borrow::Cow<'_, T> {
|
impl<T: FastWritable + alloc::borrow::ToOwned> FastWritable for alloc::borrow::Cow<'_, T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
|
fn write_into<W: fmt::Write + ?Sized>(
|
||||||
T::write_into(self.as_ref(), dest)
|
&self,
|
||||||
|
dest: &mut W,
|
||||||
|
values: &dyn Values,
|
||||||
|
) -> crate::Result<()> {
|
||||||
|
T::write_into(self.as_ref(), dest, values)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -540,8 +572,12 @@ const _: () = {
|
|||||||
($($ty:ty)*) => { $(
|
($($ty:ty)*) => { $(
|
||||||
impl FastWritable for $ty {
|
impl FastWritable for $ty {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
|
fn write_into<W: fmt::Write + ?Sized>(
|
||||||
itoa::Buffer::new().format(*self).write_into(dest)
|
&self,
|
||||||
|
dest: &mut W,
|
||||||
|
values: &dyn Values,
|
||||||
|
) -> crate::Result<()> {
|
||||||
|
itoa::Buffer::new().format(*self).write_into(dest, values)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)* };
|
)* };
|
||||||
@ -557,8 +593,12 @@ const _: () = {
|
|||||||
($($id:ident)*) => { $(
|
($($id:ident)*) => { $(
|
||||||
impl FastWritable for core::num::$id {
|
impl FastWritable for core::num::$id {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
|
fn write_into<W: fmt::Write + ?Sized>(
|
||||||
self.get().write_into(dest)
|
&self,
|
||||||
|
dest: &mut W,
|
||||||
|
values: &dyn Values,
|
||||||
|
) -> crate::Result<()> {
|
||||||
|
self.get().write_into(dest, values)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)* };
|
)* };
|
||||||
@ -571,7 +611,11 @@ const _: () = {
|
|||||||
|
|
||||||
impl FastWritable for str {
|
impl FastWritable for str {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
|
fn write_into<W: fmt::Write + ?Sized>(
|
||||||
|
&self,
|
||||||
|
dest: &mut W,
|
||||||
|
_: &dyn Values,
|
||||||
|
) -> crate::Result<()> {
|
||||||
Ok(dest.write_str(self)?)
|
Ok(dest.write_str(self)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -579,14 +623,22 @@ const _: () = {
|
|||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
impl FastWritable for alloc::string::String {
|
impl FastWritable for alloc::string::String {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
|
fn write_into<W: fmt::Write + ?Sized>(
|
||||||
self.as_str().write_into(dest)
|
&self,
|
||||||
|
dest: &mut W,
|
||||||
|
values: &dyn Values,
|
||||||
|
) -> crate::Result<()> {
|
||||||
|
self.as_str().write_into(dest, values)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FastWritable for bool {
|
impl FastWritable for bool {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
|
fn write_into<W: fmt::Write + ?Sized>(
|
||||||
|
&self,
|
||||||
|
dest: &mut W,
|
||||||
|
_: &dyn Values,
|
||||||
|
) -> crate::Result<()> {
|
||||||
Ok(dest.write_str(match self {
|
Ok(dest.write_str(match self {
|
||||||
true => "true",
|
true => "true",
|
||||||
false => "false",
|
false => "false",
|
||||||
@ -596,13 +648,21 @@ const _: () = {
|
|||||||
|
|
||||||
impl FastWritable for char {
|
impl FastWritable for char {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
|
fn write_into<W: fmt::Write + ?Sized>(
|
||||||
|
&self,
|
||||||
|
dest: &mut W,
|
||||||
|
_: &dyn Values,
|
||||||
|
) -> crate::Result<()> {
|
||||||
Ok(dest.write_char(*self)?)
|
Ok(dest.write_char(*self)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FastWritable for fmt::Arguments<'_> {
|
impl FastWritable for fmt::Arguments<'_> {
|
||||||
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
|
fn write_into<W: fmt::Write + ?Sized>(
|
||||||
|
&self,
|
||||||
|
dest: &mut W,
|
||||||
|
_: &dyn Values,
|
||||||
|
) -> crate::Result<()> {
|
||||||
Ok(match self.as_str() {
|
Ok(match self.as_str() {
|
||||||
Some(s) => dest.write_str(s),
|
Some(s) => dest.write_str(s),
|
||||||
None => dest.write_fmt(*self),
|
None => dest.write_fmt(*self),
|
||||||
@ -626,9 +686,9 @@ const _: () = {
|
|||||||
fn askama_write<W: fmt::Write + ?Sized>(
|
fn askama_write<W: fmt::Write + ?Sized>(
|
||||||
&self,
|
&self,
|
||||||
dest: &mut W,
|
dest: &mut W,
|
||||||
_: &dyn Values,
|
values: &dyn Values,
|
||||||
) -> crate::Result<()> {
|
) -> crate::Result<()> {
|
||||||
self.0.write_into(dest)
|
self.0.write_into(dest, values)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ use core::mem::MaybeUninit;
|
|||||||
|
|
||||||
use super::FastWritable;
|
use super::FastWritable;
|
||||||
use crate::ascii_str::{AsciiChar, AsciiStr};
|
use crate::ascii_str::{AsciiChar, AsciiStr};
|
||||||
|
use crate::{NO_VALUES, Values};
|
||||||
|
|
||||||
/// Returns adequate string representation (in KB, ..) of number of bytes
|
/// Returns adequate string representation (in KB, ..) of number of bytes
|
||||||
///
|
///
|
||||||
@ -33,14 +34,18 @@ pub struct FilesizeFormatFilter(f32);
|
|||||||
impl fmt::Display for FilesizeFormatFilter {
|
impl fmt::Display for FilesizeFormatFilter {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
Ok(self.write_into(f)?)
|
Ok(self.write_into(f, NO_VALUES)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FastWritable for FilesizeFormatFilter {
|
impl FastWritable for FilesizeFormatFilter {
|
||||||
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
|
fn write_into<W: fmt::Write + ?Sized>(
|
||||||
|
&self,
|
||||||
|
dest: &mut W,
|
||||||
|
values: &dyn Values,
|
||||||
|
) -> crate::Result<()> {
|
||||||
if self.0 < 1e3 {
|
if self.0 < 1e3 {
|
||||||
(self.0 as u32).write_into(dest)?;
|
(self.0 as u32).write_into(dest, values)?;
|
||||||
Ok(dest.write_str(" B")?)
|
Ok(dest.write_str(" B")?)
|
||||||
} else if let Some((prefix, factor)) = SI_PREFIXES
|
} else if let Some((prefix, factor)) = SI_PREFIXES
|
||||||
.iter()
|
.iter()
|
||||||
@ -49,8 +54,8 @@ impl FastWritable for FilesizeFormatFilter {
|
|||||||
{
|
{
|
||||||
// u32 is big enough to hold the number 999_999
|
// u32 is big enough to hold the number 999_999
|
||||||
let scaled = (self.0 * factor) as u32;
|
let scaled = (self.0 * factor) as u32;
|
||||||
(scaled / 100).write_into(dest)?;
|
(scaled / 100).write_into(dest, values)?;
|
||||||
format_frac(&mut MaybeUninit::uninit(), prefix, scaled).write_into(dest)
|
format_frac(&mut MaybeUninit::uninit(), prefix, scaled).write_into(dest, values)
|
||||||
} else {
|
} else {
|
||||||
too_big(self.0, dest)
|
too_big(self.0, dest)
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ use serde_json::ser::{CompactFormatter, PrettyFormatter, Serializer};
|
|||||||
|
|
||||||
use super::FastWritable;
|
use super::FastWritable;
|
||||||
use crate::ascii_str::{AsciiChar, AsciiStr};
|
use crate::ascii_str::{AsciiChar, AsciiStr};
|
||||||
|
use crate::{NO_VALUES, Values};
|
||||||
|
|
||||||
/// Serialize to JSON (requires `json` feature)
|
/// Serialize to JSON (requires `json` feature)
|
||||||
///
|
///
|
||||||
@ -188,7 +189,8 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Serialize> FastWritable for ToJson<S> {
|
impl<S: Serialize> FastWritable for ToJson<S> {
|
||||||
fn write_into<W: fmt::Write + ?Sized>(&self, f: &mut W) -> crate::Result<()> {
|
#[inline]
|
||||||
|
fn write_into<W: fmt::Write + ?Sized>(&self, f: &mut W, _: &dyn Values) -> crate::Result<()> {
|
||||||
serialize(f, &self.value, CompactFormatter)
|
serialize(f, &self.value, CompactFormatter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -196,12 +198,13 @@ impl<S: Serialize> FastWritable for ToJson<S> {
|
|||||||
impl<S: Serialize> fmt::Display for ToJson<S> {
|
impl<S: Serialize> fmt::Display for ToJson<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
Ok(self.write_into(f)?)
|
Ok(self.write_into(f, NO_VALUES)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Serialize, I: AsIndent> FastWritable for ToJsonPretty<S, I> {
|
impl<S: Serialize, I: AsIndent> FastWritable for ToJsonPretty<S, I> {
|
||||||
fn write_into<W: fmt::Write + ?Sized>(&self, f: &mut W) -> crate::Result<()> {
|
#[inline]
|
||||||
|
fn write_into<W: fmt::Write + ?Sized>(&self, f: &mut W, _: &dyn Values) -> crate::Result<()> {
|
||||||
serialize(
|
serialize(
|
||||||
f,
|
f,
|
||||||
&self.value,
|
&self.value,
|
||||||
@ -213,11 +216,10 @@ impl<S: Serialize, I: AsIndent> FastWritable for ToJsonPretty<S, I> {
|
|||||||
impl<S: Serialize, I: AsIndent> fmt::Display for ToJsonPretty<S, I> {
|
impl<S: Serialize, I: AsIndent> fmt::Display for ToJsonPretty<S, I> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
Ok(self.write_into(f)?)
|
Ok(self.write_into(f, NO_VALUES)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn serialize<S, W, F>(dest: &mut W, value: &S, formatter: F) -> Result<(), crate::Error>
|
fn serialize<S, W, F>(dest: &mut W, value: &S, formatter: F) -> Result<(), crate::Error>
|
||||||
where
|
where
|
||||||
S: Serialize + ?Sized,
|
S: Serialize + ?Sized,
|
||||||
|
@ -4,6 +4,7 @@ use std::fmt::Write;
|
|||||||
|
|
||||||
use percent_encoding::{AsciiSet, NON_ALPHANUMERIC, utf8_percent_encode};
|
use percent_encoding::{AsciiSet, NON_ALPHANUMERIC, utf8_percent_encode};
|
||||||
|
|
||||||
|
use crate::Values;
|
||||||
use crate::filters::{FastWritable, HtmlSafeOutput};
|
use crate::filters::{FastWritable, HtmlSafeOutput};
|
||||||
|
|
||||||
// Urlencode char encoding set. Only the characters in the unreserved set don't
|
// Urlencode char encoding set. Only the characters in the unreserved set don't
|
||||||
@ -110,8 +111,12 @@ impl<T: fmt::Display> fmt::Display for UrlencodeFilter<T> {
|
|||||||
|
|
||||||
impl<T: FastWritable> FastWritable for UrlencodeFilter<T> {
|
impl<T: FastWritable> FastWritable for UrlencodeFilter<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_into<W: fmt::Write + ?Sized>(&self, f: &mut W) -> crate::Result<()> {
|
fn write_into<W: fmt::Write + ?Sized>(
|
||||||
self.0.write_into(&mut UrlencodeWriter(f, self.1))
|
&self,
|
||||||
|
f: &mut W,
|
||||||
|
values: &dyn Values,
|
||||||
|
) -> crate::Result<()> {
|
||||||
|
self.0.write_into(&mut UrlencodeWriter(f, self.1), values)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ use core::iter::{Enumerate, Peekable};
|
|||||||
use core::ops::Deref;
|
use core::ops::Deref;
|
||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
|
|
||||||
|
use crate::Values;
|
||||||
pub use crate::error::{ErrorMarker, ResultConverter};
|
pub use crate::error::{ErrorMarker, ResultConverter};
|
||||||
use crate::filters::FastWritable;
|
use crate::filters::FastWritable;
|
||||||
pub use crate::values::get_value;
|
pub use crate::values::get_value;
|
||||||
@ -245,7 +246,7 @@ impl fmt::Display for Empty {
|
|||||||
|
|
||||||
impl FastWritable for Empty {
|
impl FastWritable for Empty {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_into<W: fmt::Write + ?Sized>(&self, _: &mut W) -> crate::Result<()> {
|
fn write_into<W: fmt::Write + ?Sized>(&self, _: &mut W, _: &dyn Values) -> crate::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -267,9 +268,13 @@ impl<L: fmt::Display, R: fmt::Display> fmt::Display for Concat<L, R> {
|
|||||||
|
|
||||||
impl<L: FastWritable, R: FastWritable> FastWritable for Concat<L, R> {
|
impl<L: FastWritable, R: FastWritable> FastWritable for Concat<L, R> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> crate::Result<()> {
|
fn write_into<W: fmt::Write + ?Sized>(
|
||||||
self.0.write_into(dest)?;
|
&self,
|
||||||
self.1.write_into(dest)
|
dest: &mut W,
|
||||||
|
values: &dyn Values,
|
||||||
|
) -> crate::Result<()> {
|
||||||
|
self.0.write_into(dest, values)?;
|
||||||
|
self.1.write_into(dest, values)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -406,8 +406,12 @@ mod tests {
|
|||||||
|
|
||||||
impl filters::FastWritable for Test {
|
impl filters::FastWritable for Test {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_into<W: fmt::Write + ?Sized>(&self, f: &mut W) -> crate::Result<()> {
|
fn write_into<W: fmt::Write + ?Sized>(
|
||||||
self.render_into(f)
|
&self,
|
||||||
|
f: &mut W,
|
||||||
|
values: &dyn Values,
|
||||||
|
) -> crate::Result<()> {
|
||||||
|
self.render_into_with_values(f, values)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,11 +310,15 @@ impl<'a, 'h> Generator<'a, 'h> {
|
|||||||
impl #wrapper_impl_generics askama::filters::FastWritable
|
impl #wrapper_impl_generics askama::filters::FastWritable
|
||||||
for #wrapper_id #wrapper_ty_generics #wrapper_where_clause {
|
for #wrapper_id #wrapper_ty_generics #wrapper_where_clause {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_into<AskamaW>(&self, dest: &mut AskamaW) -> askama::Result<()>
|
fn write_into<AskamaW>(
|
||||||
|
&self,
|
||||||
|
dest: &mut AskamaW,
|
||||||
|
values: &dyn askama::Values,
|
||||||
|
) -> askama::Result<()>
|
||||||
where
|
where
|
||||||
AskamaW: askama::helpers::core::fmt::Write + ?askama::helpers::core::marker::Sized
|
AskamaW: askama::helpers::core::fmt::Write + ?askama::helpers::core::marker::Sized
|
||||||
{
|
{
|
||||||
<_ as askama::Template>::render_into(self, dest)
|
<_ as askama::Template>::render_into_with_values(self, dest, values)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,11 +64,15 @@ fn impl_fast_writable(ast: &DeriveInput, buf: &mut Buffer) {
|
|||||||
buf.write(
|
buf.write(
|
||||||
"\
|
"\
|
||||||
#[inline]\
|
#[inline]\
|
||||||
fn write_into<AskamaW>(&self, dest: &mut AskamaW) -> askama::Result<()> \
|
fn write_into<AskamaW>(\
|
||||||
|
&self,\
|
||||||
|
dest: &mut AskamaW,\
|
||||||
|
values: &dyn askama::Values\
|
||||||
|
) -> askama::Result<()> \
|
||||||
where \
|
where \
|
||||||
AskamaW: askama::helpers::core::fmt::Write + ?askama::helpers::core::marker::Sized,\
|
AskamaW: askama::helpers::core::fmt::Write + ?askama::helpers::core::marker::Sized,\
|
||||||
{\
|
{\
|
||||||
askama::Template::render_into(self, dest)\
|
askama::Template::render_into_with_values(self, dest, values)\
|
||||||
}\
|
}\
|
||||||
}",
|
}",
|
||||||
);
|
);
|
||||||
|
@ -69,11 +69,15 @@ fn compare_ex(
|
|||||||
|
|
||||||
impl askama::filters::FastWritable for Foo {
|
impl askama::filters::FastWritable for Foo {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write_into<AskamaW>(&self, dest: &mut AskamaW) -> askama::Result<()>
|
fn write_into<AskamaW>(
|
||||||
|
&self,
|
||||||
|
dest: &mut AskamaW,
|
||||||
|
values: &dyn askama::Values,
|
||||||
|
) -> askama::Result<()>
|
||||||
where
|
where
|
||||||
AskamaW: askama::helpers::core::fmt::Write + ?askama::helpers::core::marker::Sized,
|
AskamaW: askama::helpers::core::fmt::Write + ?askama::helpers::core::marker::Sized,
|
||||||
{
|
{
|
||||||
askama::Template::render_into(self, dest)
|
askama::Template::render_into_with_values(self, dest, values)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -88,3 +88,26 @@ fn test_value_function_getter() {
|
|||||||
values.insert("a".to_string(), Box::new(false));
|
values.insert("a".to_string(), Box::new(false));
|
||||||
assert_eq!(V.render_with_values(&values).unwrap(), "");
|
assert_eq!(V.render_with_values(&values).unwrap(), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_value_in_subtemplates() {
|
||||||
|
// In this test we make sure that values are passed down to transcluded sub-templates,
|
||||||
|
// even if there is a filter in the mix, e.g. the implicit `|escape` filter.
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(source = r#"{{ Child }}"#, ext = "html")]
|
||||||
|
struct Parent;
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(
|
||||||
|
source = r#"Hello, {{ askama::get_value::<String>("who")? }}!"#,
|
||||||
|
ext = "html"
|
||||||
|
)]
|
||||||
|
struct Child;
|
||||||
|
|
||||||
|
let values: (&str, &dyn Any) = ("who", &"<world>".to_owned());
|
||||||
|
assert_eq!(
|
||||||
|
Parent.render_with_values(&values).unwrap(),
|
||||||
|
"Hello, &#60;world&#62;!", // sic: escaped twice
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user