Skip to content

Commit

Permalink
Implement traits for Pin<T> properly, for all T
Browse files Browse the repository at this point in the history
  • Loading branch information
Kijewski committed Oct 20, 2024
1 parent 81d39cc commit f48d265
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 8 deletions.
15 changes: 15 additions & 0 deletions rinja/src/filters/builtin.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -840,6 +842,19 @@ const _: () = {
}
}

impl<T> PluralizeCount for Pin<T>
where
T: Deref,
<T as Deref>::Target: PluralizeCount,
{
type Error = <<T as Deref>::Target as PluralizeCount>::Error;

#[inline]
fn is_singular(&self) -> Result<bool, Self::Error> {
self.as_ref().get_ref().is_singular()
}
}

/// implement `PluralizeCount` for unsigned integer types
macro_rules! impl_pluralize_for_unsigned_int {
($($ty:ty)*) => { $(
Expand Down
13 changes: 13 additions & 0 deletions rinja/src/filters/escape.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -511,6 +513,17 @@ const _: () = {
}
}

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) -> fmt::Result {
self.as_ref().get_ref().write_into(dest)
}
}

impl<T: FastWritable + ToOwned> FastWritable for borrow::Cow<'_, T> {
#[inline]
fn write_into<W: fmt::Write + ?Sized>(&self, dest: &mut W) -> fmt::Result {
Expand Down
13 changes: 13 additions & 0 deletions rinja/src/filters/json.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use std::convert::Infallible;
use std::ops::Deref;
use std::pin::Pin;
use std::{fmt, io, str};

use serde::Serialize;
Expand Down Expand Up @@ -153,6 +155,17 @@ crate::impl_for_ref! {
}
}

impl<T> AsIndent for Pin<T>
where
T: Deref,
<T as Deref>::Target: AsIndent,
{
#[inline]
fn as_indent(&self) -> &str {
self.as_ref().get_ref().as_indent()
}
}

impl<S: Serialize> FastWritable for ToJson<S> {
#[inline]
fn write_into<W: fmt::Write + ?Sized>(&self, f: &mut W) -> fmt::Result {
Expand Down
27 changes: 24 additions & 3 deletions rinja/src/helpers.rs
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -91,7 +93,8 @@ where
}
}

pub fn get_primitive_value<T: PrimitiveType>(value: &T) -> T::Value {
#[inline]
pub fn get_primitive_value<T: PrimitiveType>(value: T) -> T::Value {
value.get()
}

Expand Down Expand Up @@ -132,18 +135,36 @@ crate::impl_for_ref! {
}
}

impl<T> PrimitiveType for Pin<T>
where
T: Deref,
<T as Deref>::Target: PrimitiveType,
{
type Value = <<T as Deref>::Target as PrimitiveType>::Value;

#[inline]
fn get(&self) -> Self::Value {
self.as_ref().get_ref().get()
}
}

/// Implement [`PrimitiveType`] for [`Cell<T>`]
///
/// ```
/// # 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<i16>
/// value: &'a Pin<Rc<Cell<i16>>>
/// }
///
/// assert_eq!(Test { value: &Cell::new(-1) }.to_string(), "65535");
/// assert_eq!(
/// Test { value: &Rc::pin(Cell::new(-1)) }.to_string(),
/// "65535",
/// );
/// ```
impl<T: PrimitiveType + Copy> PrimitiveType for Cell<T> {
type Value = T::Value;
Expand Down
8 changes: 3 additions & 5 deletions rinja/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,6 @@ macro_rules! impl_for_ref {
Box<T>
std::cell::Ref<'_, T>
std::cell::RefMut<'_, T>
std::pin::Pin<&T>
std::pin::Pin<&mut T>
std::rc::Rc<T>
std::sync::Arc<T>
std::sync::MutexGuard<'_, T>
Expand All @@ -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;
Expand Down

0 comments on commit f48d265

Please sign in to comment.