diff --git a/rinja/src/filters/builtin.rs b/rinja/src/filters/builtin.rs index 88f6fc70c..c8a2fa32e 100644 --- a/rinja/src/filters/builtin.rs +++ b/rinja/src/filters/builtin.rs @@ -1,6 +1,8 @@ use std::cell::Cell; use std::convert::Infallible; use std::fmt::{self, Write}; +use std::ops::Deref; +use std::pin::Pin; use super::escape::{FastWritable, HtmlSafeOutput}; use crate::{Error, Result}; @@ -840,6 +842,19 @@ const _: () = { } } + impl PluralizeCount for Pin + where + T: Deref, + ::Target: PluralizeCount, + { + type Error = <::Target as PluralizeCount>::Error; + + #[inline] + fn is_singular(&self) -> Result { + self.as_ref().get_ref().is_singular() + } + } + /// implement `PluralizeCount` for unsigned integer types macro_rules! impl_pluralize_for_unsigned_int { ($($ty:ty)*) => { $( diff --git a/rinja/src/filters/escape.rs b/rinja/src/filters/escape.rs index 8b068a8bf..0f5a45be9 100644 --- a/rinja/src/filters/escape.rs +++ b/rinja/src/filters/escape.rs @@ -1,5 +1,7 @@ use std::convert::Infallible; use std::fmt::{self, Formatter, Write}; +use std::ops::Deref; +use std::pin::Pin; use std::{borrow, str}; /// Marks a string (or other `Display` type) as safe @@ -511,6 +513,17 @@ const _: () = { } } + impl FastWritable for Pin + where + T: Deref, + ::Target: FastWritable, + { + #[inline] + fn write_into(&self, dest: &mut W) -> fmt::Result { + self.as_ref().get_ref().write_into(dest) + } + } + impl FastWritable for borrow::Cow<'_, T> { #[inline] fn write_into(&self, dest: &mut W) -> fmt::Result { diff --git a/rinja/src/filters/json.rs b/rinja/src/filters/json.rs index 1a2a1fa6c..d1026bd2f 100644 --- a/rinja/src/filters/json.rs +++ b/rinja/src/filters/json.rs @@ -1,4 +1,6 @@ use std::convert::Infallible; +use std::ops::Deref; +use std::pin::Pin; use std::{fmt, io, str}; use serde::Serialize; @@ -153,6 +155,17 @@ crate::impl_for_ref! { } } +impl AsIndent for Pin +where + T: Deref, + ::Target: AsIndent, +{ + #[inline] + fn as_indent(&self) -> &str { + self.as_ref().get_ref().as_indent() + } +} + impl FastWritable for ToJson { #[inline] fn write_into(&self, f: &mut W) -> fmt::Result { diff --git a/rinja/src/helpers.rs b/rinja/src/helpers.rs index 51db0353d..07bcc98d5 100644 --- a/rinja/src/helpers.rs +++ b/rinja/src/helpers.rs @@ -1,6 +1,8 @@ use std::cell::Cell; use std::fmt; use std::iter::{Enumerate, Peekable}; +use std::ops::Deref; +use std::pin::Pin; // The re-exports are used in the generated code for macro hygiene. Even if the paths `::core` or // `::std` are shadowed, the generated code will still be able to access the crates. @@ -91,7 +93,8 @@ where } } -pub fn get_primitive_value(value: &T) -> T::Value { +#[inline] +pub fn get_primitive_value(value: T) -> T::Value { value.get() } @@ -132,18 +135,36 @@ crate::impl_for_ref! { } } +impl PrimitiveType for Pin +where + T: Deref, + ::Target: PrimitiveType, +{ + type Value = <::Target as PrimitiveType>::Value; + + #[inline] + fn get(&self) -> Self::Value { + self.as_ref().get_ref().get() + } +} + /// Implement [`PrimitiveType`] for [`Cell`] /// /// ``` /// # use std::cell::Cell; +/// # use std::rc::Rc; +/// # use std::pin::Pin; /// # use rinja::Template; /// #[derive(Template)] /// #[template(ext = "txt", source = "{{ value as u16 }}")] /// struct Test<'a> { -/// value: &'a Cell +/// value: &'a Pin>> /// } /// -/// assert_eq!(Test { value: &Cell::new(-1) }.to_string(), "65535"); +/// assert_eq!( +/// Test { value: &Rc::pin(Cell::new(-1)) }.to_string(), +/// "65535", +/// ); /// ``` impl PrimitiveType for Cell { type Value = T::Value; diff --git a/rinja/src/lib.rs b/rinja/src/lib.rs index 77e0f487a..1baa77d7d 100644 --- a/rinja/src/lib.rs +++ b/rinja/src/lib.rs @@ -240,8 +240,6 @@ macro_rules! impl_for_ref { Box std::cell::Ref<'_, T> std::cell::RefMut<'_, T> - std::pin::Pin<&T> - std::pin::Pin<&mut T> std::rc::Rc std::sync::Arc std::sync::MutexGuard<'_, T> @@ -250,9 +248,9 @@ macro_rules! impl_for_ref { ] $body } }; - (impl<$T:ident> $Trait:ident for [$($ty:ty)*] $body:tt) => { $( - impl<$T: $Trait + ?Sized> $Trait for $ty $body - )+ } + (impl<$T:ident> $Trait:ident for [$($ty:ty)*] $body:tt) => { + $(impl<$T: $Trait + ?Sized> $Trait for $ty $body)* + } } pub(crate) use impl_for_ref;