mirror of
https://github.com/askama-rs/askama.git
synced 2025-10-01 06:51:15 +00:00
Move FastWritable
into askama
root
This commit is contained in:
parent
7c5deda4c1
commit
6f912abee6
@ -7,9 +7,9 @@ use core::fmt::{self, Write};
|
||||
use core::ops::Deref;
|
||||
use core::pin::Pin;
|
||||
|
||||
use super::MAX_LEN;
|
||||
use super::escape::HtmlSafeOutput;
|
||||
use super::{FastWritable, MAX_LEN};
|
||||
use crate::Result;
|
||||
use crate::{FastWritable, Result};
|
||||
|
||||
/// Return an ephemeral `&str` for `$src: impl fmt::Display`
|
||||
///
|
||||
|
@ -5,8 +5,7 @@ use core::ops::Deref;
|
||||
use core::pin::Pin;
|
||||
|
||||
use super::MAX_LEN;
|
||||
use super::escape::FastWritable;
|
||||
use crate::{Error, Result, Values};
|
||||
use crate::{Error, FastWritable, Result, Values};
|
||||
|
||||
/// Limit string length, appends '...' if truncated
|
||||
///
|
||||
|
@ -1,10 +1,9 @@
|
||||
use core::convert::Infallible;
|
||||
use core::fmt::{self, Formatter, Write};
|
||||
use core::ops::Deref;
|
||||
use core::pin::Pin;
|
||||
use core::str;
|
||||
|
||||
use crate::Values;
|
||||
use crate::{FastWritable, Values};
|
||||
|
||||
/// Marks a string (or other `Display` type) as safe
|
||||
///
|
||||
@ -518,196 +517,6 @@ pub trait WriteWritable {
|
||||
) -> crate::Result<()>;
|
||||
}
|
||||
|
||||
/// Used internally by askama to speed up writing some types.
|
||||
///
|
||||
/// Types implementing this trait can be written without needing to employ an [`fmt::Formatter`].
|
||||
pub trait FastWritable {
|
||||
/// Used internally by askama to speed up writing some types.
|
||||
fn write_into<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
values: &dyn Values,
|
||||
) -> crate::Result<()>;
|
||||
}
|
||||
|
||||
const _: () = {
|
||||
crate::impl_for_ref! {
|
||||
impl FastWritable for T {
|
||||
#[inline]
|
||||
fn write_into<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
values: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
<T>::write_into(self, dest, values)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> FastWritable for Pin<T>
|
||||
where
|
||||
T: Deref,
|
||||
<T as Deref>::Target: FastWritable,
|
||||
{
|
||||
#[inline]
|
||||
fn write_into<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
values: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
self.as_ref().get_ref().write_into(dest, values)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
impl<T: FastWritable + alloc::borrow::ToOwned> FastWritable for alloc::borrow::Cow<'_, T> {
|
||||
#[inline]
|
||||
fn write_into<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
values: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
T::write_into(self.as_ref(), dest, values)
|
||||
}
|
||||
}
|
||||
|
||||
// implement FastWritable for a list of types
|
||||
macro_rules! impl_for_int {
|
||||
($($ty:ty)*) => { $(
|
||||
impl FastWritable for $ty {
|
||||
#[inline]
|
||||
fn write_into<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
values: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
itoa::Buffer::new().format(*self).write_into(dest, values)
|
||||
}
|
||||
}
|
||||
)* };
|
||||
}
|
||||
|
||||
impl_for_int!(
|
||||
u8 u16 u32 u64 u128 usize
|
||||
i8 i16 i32 i64 i128 isize
|
||||
);
|
||||
|
||||
// implement FastWritable for a list of non-zero integral types
|
||||
macro_rules! impl_for_nz_int {
|
||||
($($id:ident)*) => { $(
|
||||
impl FastWritable for core::num::$id {
|
||||
#[inline]
|
||||
fn write_into<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
values: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
self.get().write_into(dest, values)
|
||||
}
|
||||
}
|
||||
)* };
|
||||
}
|
||||
|
||||
impl_for_nz_int!(
|
||||
NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize
|
||||
NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize
|
||||
);
|
||||
|
||||
impl FastWritable for str {
|
||||
#[inline]
|
||||
fn write_into<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
_: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
Ok(dest.write_str(self)?)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
impl FastWritable for alloc::string::String {
|
||||
#[inline]
|
||||
fn write_into<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
values: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
self.as_str().write_into(dest, values)
|
||||
}
|
||||
}
|
||||
|
||||
impl FastWritable for bool {
|
||||
#[inline]
|
||||
fn write_into<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
_: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
Ok(dest.write_str(match self {
|
||||
true => "true",
|
||||
false => "false",
|
||||
})?)
|
||||
}
|
||||
}
|
||||
|
||||
impl FastWritable for char {
|
||||
#[inline]
|
||||
fn write_into<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
_: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
Ok(dest.write_char(*self)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl FastWritable for fmt::Arguments<'_> {
|
||||
fn write_into<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
_: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
Ok(match self.as_str() {
|
||||
Some(s) => dest.write_str(s),
|
||||
None => dest.write_fmt(*self),
|
||||
}?)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: crate::Template + ?Sized> WriteWritable for &Writable<'_, S> {
|
||||
#[inline]
|
||||
fn askama_write<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
values: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
self.0.render_into_with_values(dest, values)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: FastWritable + ?Sized> WriteWritable for &&Writable<'_, S> {
|
||||
#[inline]
|
||||
fn askama_write<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
values: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
self.0.write_into(dest, values)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: fmt::Display + ?Sized> WriteWritable for &&&Writable<'_, S> {
|
||||
#[inline]
|
||||
fn askama_write<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
_: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
Ok(write!(dest, "{}", self.0)?)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "alloc")]
|
||||
fn test_escape() {
|
||||
|
@ -2,9 +2,8 @@ use core::convert::Infallible;
|
||||
use core::fmt;
|
||||
use core::mem::MaybeUninit;
|
||||
|
||||
use super::FastWritable;
|
||||
use crate::ascii_str::{AsciiChar, AsciiStr};
|
||||
use crate::{NO_VALUES, Values};
|
||||
use crate::{FastWritable, NO_VALUES, Values};
|
||||
|
||||
/// Returns adequate string representation (in KB, ..) of number of bytes
|
||||
///
|
||||
|
@ -4,9 +4,9 @@ use std::{fmt, io, str};
|
||||
use serde::Serialize;
|
||||
use serde_json::ser::{CompactFormatter, PrettyFormatter, Serializer};
|
||||
|
||||
use super::{AsIndent, FastWritable};
|
||||
use super::AsIndent;
|
||||
use crate::ascii_str::{AsciiChar, AsciiStr};
|
||||
use crate::{NO_VALUES, Values};
|
||||
use crate::{FastWritable, NO_VALUES, Values};
|
||||
|
||||
/// Serialize to JSON (requires `json` feature)
|
||||
///
|
||||
|
@ -27,8 +27,8 @@ pub use self::alloc::{
|
||||
};
|
||||
pub use self::builtin::{PluralizeCount, center, join, pluralize, truncate};
|
||||
pub use self::escape::{
|
||||
AutoEscape, AutoEscaper, Escaper, FastWritable, Html, HtmlSafe, HtmlSafeOutput, MaybeSafe,
|
||||
Safe, Text, Unsafe, Writable, WriteWritable, e, escape, safe,
|
||||
AutoEscape, AutoEscaper, Escaper, Html, HtmlSafe, HtmlSafeOutput, MaybeSafe, Safe, Text,
|
||||
Unsafe, Writable, WriteWritable, e, escape, safe,
|
||||
};
|
||||
pub use self::humansize::filesizeformat;
|
||||
#[cfg(feature = "serde_json")]
|
||||
|
@ -4,8 +4,8 @@ use std::fmt::Write;
|
||||
|
||||
use percent_encoding::{AsciiSet, NON_ALPHANUMERIC, utf8_percent_encode};
|
||||
|
||||
use crate::Values;
|
||||
use crate::filters::{FastWritable, HtmlSafeOutput};
|
||||
use crate::filters::HtmlSafeOutput;
|
||||
use crate::{FastWritable, Values};
|
||||
|
||||
// Urlencode char encoding set. Only the characters in the unreserved set don't
|
||||
// have any special purpose in any part of a URI and can be safely left
|
||||
|
@ -12,10 +12,9 @@ use core::iter::{Enumerate, Peekable};
|
||||
use core::ops::Deref;
|
||||
use core::pin::Pin;
|
||||
|
||||
use crate::Values;
|
||||
pub use crate::error::{ErrorMarker, ResultConverter};
|
||||
use crate::filters::FastWritable;
|
||||
pub use crate::values::get_value;
|
||||
use crate::{FastWritable, Values};
|
||||
|
||||
pub struct TemplateLoop<I>
|
||||
where
|
||||
|
@ -76,6 +76,7 @@ mod values;
|
||||
#[cfg(feature = "alloc")]
|
||||
use alloc::string::String;
|
||||
use core::fmt;
|
||||
use core::ops::Deref;
|
||||
#[cfg(feature = "std")]
|
||||
use std::io;
|
||||
|
||||
@ -109,7 +110,7 @@ pub use crate::values::{NO_VALUES, Value, Values, get_value};
|
||||
/// `.render()`.
|
||||
///
|
||||
/// [dynamic methods calls]: <https://doc.rust-lang.org/stable/std/keyword.dyn.html>
|
||||
pub trait Template: fmt::Display + filters::FastWritable {
|
||||
pub trait Template: fmt::Display + FastWritable {
|
||||
/// Helper method which allocates a new `String` and renders into it.
|
||||
#[inline]
|
||||
#[cfg(feature = "alloc")]
|
||||
@ -370,6 +371,194 @@ macro_rules! impl_for_ref {
|
||||
}
|
||||
}
|
||||
|
||||
/// Types implementing this trait can be written without needing to employ an [`fmt::Formatter`].
|
||||
pub trait FastWritable {
|
||||
/// Used internally by askama to speed up writing some types.
|
||||
fn write_into<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
values: &dyn Values,
|
||||
) -> crate::Result<()>;
|
||||
}
|
||||
|
||||
const _: () = {
|
||||
crate::impl_for_ref! {
|
||||
impl FastWritable for T {
|
||||
#[inline]
|
||||
fn write_into<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
values: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
<T>::write_into(self, dest, values)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> FastWritable for core::pin::Pin<T>
|
||||
where
|
||||
T: Deref,
|
||||
<T as Deref>::Target: FastWritable,
|
||||
{
|
||||
#[inline]
|
||||
fn write_into<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
values: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
self.as_ref().get_ref().write_into(dest, values)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
impl<T: FastWritable + alloc::borrow::ToOwned> FastWritable for alloc::borrow::Cow<'_, T> {
|
||||
#[inline]
|
||||
fn write_into<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
values: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
T::write_into(self.as_ref(), dest, values)
|
||||
}
|
||||
}
|
||||
|
||||
// implement FastWritable for a list of types
|
||||
macro_rules! impl_for_int {
|
||||
($($ty:ty)*) => { $(
|
||||
impl FastWritable for $ty {
|
||||
#[inline]
|
||||
fn write_into<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
values: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
itoa::Buffer::new().format(*self).write_into(dest, values)
|
||||
}
|
||||
}
|
||||
)* };
|
||||
}
|
||||
|
||||
impl_for_int!(
|
||||
u8 u16 u32 u64 u128 usize
|
||||
i8 i16 i32 i64 i128 isize
|
||||
);
|
||||
|
||||
// implement FastWritable for a list of non-zero integral types
|
||||
macro_rules! impl_for_nz_int {
|
||||
($($id:ident)*) => { $(
|
||||
impl FastWritable for core::num::$id {
|
||||
#[inline]
|
||||
fn write_into<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
values: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
self.get().write_into(dest, values)
|
||||
}
|
||||
}
|
||||
)* };
|
||||
}
|
||||
|
||||
impl_for_nz_int!(
|
||||
NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize
|
||||
NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize
|
||||
);
|
||||
|
||||
impl FastWritable for str {
|
||||
#[inline]
|
||||
fn write_into<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
_: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
Ok(dest.write_str(self)?)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "alloc")]
|
||||
impl FastWritable for alloc::string::String {
|
||||
#[inline]
|
||||
fn write_into<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
values: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
self.as_str().write_into(dest, values)
|
||||
}
|
||||
}
|
||||
|
||||
impl FastWritable for bool {
|
||||
#[inline]
|
||||
fn write_into<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
_: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
Ok(dest.write_str(match self {
|
||||
true => "true",
|
||||
false => "false",
|
||||
})?)
|
||||
}
|
||||
}
|
||||
|
||||
impl FastWritable for char {
|
||||
#[inline]
|
||||
fn write_into<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
_: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
Ok(dest.write_char(*self)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl FastWritable for fmt::Arguments<'_> {
|
||||
fn write_into<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
_: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
Ok(match self.as_str() {
|
||||
Some(s) => dest.write_str(s),
|
||||
None => dest.write_fmt(*self),
|
||||
}?)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: crate::Template + ?Sized> filters::WriteWritable for &filters::Writable<'_, S> {
|
||||
#[inline]
|
||||
fn askama_write<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
values: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
self.0.render_into_with_values(dest, values)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: FastWritable + ?Sized> filters::WriteWritable for &&filters::Writable<'_, S> {
|
||||
#[inline]
|
||||
fn askama_write<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
values: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
self.0.write_into(dest, values)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: fmt::Display + ?Sized> filters::WriteWritable for &&&filters::Writable<'_, S> {
|
||||
#[inline]
|
||||
fn askama_write<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
dest: &mut W,
|
||||
_: &dyn Values,
|
||||
) -> crate::Result<()> {
|
||||
Ok(write!(dest, "{}", self.0)?)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub(crate) use impl_for_ref;
|
||||
|
||||
#[cfg(all(test, feature = "alloc"))]
|
||||
@ -404,7 +593,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
impl filters::FastWritable for Test {
|
||||
impl FastWritable for Test {
|
||||
#[inline]
|
||||
fn write_into<W: fmt::Write + ?Sized>(
|
||||
&self,
|
||||
|
@ -308,7 +308,7 @@ impl<'a, 'h> Generator<'a, 'h> {
|
||||
}
|
||||
|
||||
// cannot use `crate::integrations::impl_fast_writable()` w/o cloning the struct
|
||||
impl #wrapper_impl_generics askama::filters::FastWritable
|
||||
impl #wrapper_impl_generics askama::FastWritable
|
||||
for #wrapper_id #wrapper_ty_generics #wrapper_where_clause {
|
||||
#[inline]
|
||||
fn write_into<AskamaW>(
|
||||
|
@ -60,7 +60,7 @@ fn impl_display(ast: &DeriveInput, buf: &mut Buffer) {
|
||||
|
||||
/// Implement `FastWritable` for the given item.
|
||||
fn impl_fast_writable(ast: &DeriveInput, buf: &mut Buffer) {
|
||||
write_header(ast, buf, "askama::filters::FastWritable");
|
||||
write_header(ast, buf, "askama::FastWritable");
|
||||
buf.write(
|
||||
"\
|
||||
#[inline]\
|
||||
|
@ -67,7 +67,7 @@ fn compare_ex(
|
||||
}
|
||||
}
|
||||
|
||||
impl askama::filters::FastWritable for Foo {
|
||||
impl askama::FastWritable for Foo {
|
||||
#[inline]
|
||||
fn write_into<AskamaW>(
|
||||
&self,
|
||||
|
@ -42,7 +42,7 @@ your `FastWritable` implementation:
|
||||
|
||||
[`fmt::Display`]: <https://doc.rust-lang.org/stable/std/fmt/trait.Display.html>
|
||||
[`fmt::Formatter`]: <https://doc.rust-lang.org/stable/std/fmt/struct.Formatter.html>
|
||||
[`FastWritable`]: <./doc/askama/filters/trait.FastWritable.html>
|
||||
[`FastWritable`]: <./doc/askama/trait.FastWritable.html>
|
||||
[autoref-based specialization]: <https://lukaskalbertodt.github.io/2019/12/05/generalized-autoref-based-specialization.html>
|
||||
|
||||
## Slow Debug Recompilations
|
||||
|
@ -1,7 +1,6 @@
|
||||
use std::fmt::{self, Write};
|
||||
|
||||
use askama::NO_VALUES;
|
||||
use askama::filters::FastWritable;
|
||||
use askama::{FastWritable, NO_VALUES};
|
||||
|
||||
// In a real application, please have a look at
|
||||
// https://github.com/kdeldycke/awesome-falsehood/blob/690a070/readme.md#human-identity
|
||||
|
Loading…
x
Reference in New Issue
Block a user