Use UFCS instead of receiver coecions
This change is required to achieve filter
This commit is contained in:
parent
203a890618
commit
869c58dcb1
|
@ -271,7 +271,6 @@ fn derive_template_impl(tokens: TokenStream) -> Result<TokenStream, syn::Error>
|
|||
#include_bytes_seq;
|
||||
|
||||
use sailfish::runtime as __sf_rt;
|
||||
use __sf_rt::RenderInternal as _;
|
||||
|
||||
static SIZE_HINT: __sf_rt::SizeHint = __sf_rt::SizeHint::new();
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#[doc(hidden)]
|
||||
macro_rules! render {
|
||||
($ctx:ident, $value:expr) => {
|
||||
(&($value))._sf_r_internal(&mut $ctx.buf)?
|
||||
$crate::runtime::Render::render(&($value), &mut $ctx.buf)?
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ macro_rules! render {
|
|||
#[doc(hidden)]
|
||||
macro_rules! render_escaped {
|
||||
($ctx:ident, $value:expr) => {
|
||||
(&($value))._sf_re_internal(&mut $ctx.buf)?
|
||||
$crate::runtime::Render::render_escaped(&($value), &mut $ctx.buf)?
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
use std::path::Path;
|
||||
use std::borrow::Cow;
|
||||
use std::cell::{Ref, RefMut};
|
||||
use std::num::{
|
||||
NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize,
|
||||
NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, Wrapping,
|
||||
};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::rc::Rc;
|
||||
use std::sync::{Arc, MutexGuard, RwLockReadGuard, RwLockWriteGuard};
|
||||
|
||||
use super::buffer::Buffer;
|
||||
use super::{escape, RenderError};
|
||||
|
@ -59,16 +67,30 @@ pub trait Render {
|
|||
// }
|
||||
// }
|
||||
|
||||
impl Render for str {
|
||||
impl Render for String {
|
||||
#[inline]
|
||||
fn render(&self, b: &mut Buffer) -> Result<(), RenderError> {
|
||||
b.push_str(self);
|
||||
b.push_str(&**self);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn render_escaped(&self, b: &mut Buffer) -> Result<(), RenderError> {
|
||||
escape::escape_to_buf(self, b);
|
||||
escape::escape_to_buf(&**self, b);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for &str {
|
||||
#[inline]
|
||||
fn render(&self, b: &mut Buffer) -> Result<(), RenderError> {
|
||||
b.push_str(*self);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn render_escaped(&self, b: &mut Buffer) -> Result<(), RenderError> {
|
||||
escape::escape_to_buf(*self, b);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -94,6 +116,21 @@ impl Render for char {
|
|||
}
|
||||
}
|
||||
|
||||
impl Render for PathBuf {
|
||||
#[inline]
|
||||
fn render(&self, b: &mut Buffer) -> Result<(), RenderError> {
|
||||
// TODO: speed up on Windows using OsStrExt
|
||||
b.push_str(&*self.to_string_lossy());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn render_escaped(&self, b: &mut Buffer) -> Result<(), RenderError> {
|
||||
escape::escape_to_buf(&*self.to_string_lossy(), b);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for Path {
|
||||
#[inline]
|
||||
fn render(&self, b: &mut Buffer) -> Result<(), RenderError> {
|
||||
|
@ -236,22 +273,80 @@ impl Render for f64 {
|
|||
}
|
||||
}
|
||||
|
||||
// private trait for avoiding method name collision in render* macros
|
||||
#[doc(hidden)]
|
||||
pub trait RenderInternal {
|
||||
fn _sf_r_internal(&self, b: &mut Buffer) -> Result<(), RenderError>;
|
||||
fn _sf_re_internal(&self, b: &mut Buffer) -> Result<(), RenderError>;
|
||||
macro_rules! render_deref {
|
||||
(
|
||||
$(#[doc = $doc:tt])*
|
||||
[$($bounds:tt)+] $($desc:tt)+
|
||||
) => {
|
||||
$(#[doc = $doc])*
|
||||
impl <$($bounds)+> Render for $($desc)+ {
|
||||
#[inline]
|
||||
fn render(&self, b: &mut Buffer) -> Result<(), RenderError> {
|
||||
(**self).render(b)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn render_escaped(&self, b: &mut Buffer) -> Result<(), RenderError> {
|
||||
(**self).render_escaped(b)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl<T: Render + ?Sized> RenderInternal for T {
|
||||
render_deref!(['a, T: Render + ?Sized] &'a T);
|
||||
render_deref!(['a, T: Render + ?Sized] &'a mut T);
|
||||
render_deref!([T: Render + ?Sized] Box<T>);
|
||||
render_deref!([T: Render + ?Sized] Rc<T>);
|
||||
render_deref!([T: Render + ?Sized] Arc<T>);
|
||||
render_deref!(['a, T: Render + ToOwned + ?Sized] Cow<'a, T>);
|
||||
render_deref!(['a, T: Render + ?Sized] Ref<'a, T>);
|
||||
render_deref!(['a, T: Render + ?Sized] RefMut<'a, T>);
|
||||
render_deref!(['a, T: Render + ?Sized] MutexGuard<'a, T>);
|
||||
render_deref!(['a, T: Render + ?Sized] RwLockReadGuard<'a, T>);
|
||||
render_deref!(['a, T: Render + ?Sized] RwLockWriteGuard<'a, T>);
|
||||
|
||||
macro_rules! render_nonzero {
|
||||
($($type:ty,)*) => {
|
||||
$(
|
||||
impl Render for $type {
|
||||
#[inline]
|
||||
fn render(&self, b: &mut Buffer) -> Result<(), RenderError> {
|
||||
self.get().render(b)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn render_escaped(&self, b: &mut Buffer) -> Result<(), RenderError> {
|
||||
self.get().render_escaped(b)
|
||||
}
|
||||
}
|
||||
)*
|
||||
}
|
||||
}
|
||||
|
||||
render_nonzero!(
|
||||
NonZeroI8,
|
||||
NonZeroI16,
|
||||
NonZeroI32,
|
||||
NonZeroI64,
|
||||
NonZeroI128,
|
||||
NonZeroIsize,
|
||||
NonZeroU8,
|
||||
NonZeroU16,
|
||||
NonZeroU32,
|
||||
NonZeroU64,
|
||||
NonZeroU128,
|
||||
NonZeroUsize,
|
||||
);
|
||||
|
||||
impl<T: Render> Render for Wrapping<T> {
|
||||
#[inline]
|
||||
fn _sf_r_internal(&self, b: &mut Buffer) -> Result<(), RenderError> {
|
||||
self.render(b)
|
||||
fn render(&self, b: &mut Buffer) -> Result<(), RenderError> {
|
||||
self.0.render(b)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn _sf_re_internal(&self, b: &mut Buffer) -> Result<(), RenderError> {
|
||||
self.render_escaped(b)
|
||||
fn render_escaped(&self, b: &mut Buffer) -> Result<(), RenderError> {
|
||||
self.0.render_escaped(b)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,33 +357,33 @@ mod tests {
|
|||
#[test]
|
||||
fn receiver_coercion() {
|
||||
let mut b = Buffer::new();
|
||||
(&1)._sf_r_internal(&mut b).unwrap();
|
||||
(&&1)._sf_r_internal(&mut b).unwrap();
|
||||
(&&&1)._sf_r_internal(&mut b).unwrap();
|
||||
(&&&&1)._sf_r_internal(&mut b).unwrap();
|
||||
Render::render(&1, &mut b).unwrap();
|
||||
Render::render(&&1, &mut b).unwrap();
|
||||
Render::render(&&&1, &mut b).unwrap();
|
||||
Render::render(&&&&1, &mut b).unwrap();
|
||||
assert_eq!(b.as_str(), "1111");
|
||||
b.clear();
|
||||
|
||||
(&true)._sf_r_internal(&mut b).unwrap();
|
||||
(&&false)._sf_r_internal(&mut b).unwrap();
|
||||
(&&&true)._sf_r_internal(&mut b).unwrap();
|
||||
(&&&&false)._sf_r_internal(&mut b).unwrap();
|
||||
Render::render(&true, &mut b).unwrap();
|
||||
Render::render(&&false, &mut b).unwrap();
|
||||
Render::render(&&&true, &mut b).unwrap();
|
||||
Render::render(&&&&false, &mut b).unwrap();
|
||||
assert_eq!(b.as_str(), "truefalsetruefalse");
|
||||
b.clear();
|
||||
|
||||
let s = "apple";
|
||||
(&*s)._sf_re_internal(&mut b).unwrap();
|
||||
(&s)._sf_re_internal(&mut b).unwrap();
|
||||
(&&s)._sf_re_internal(&mut b).unwrap();
|
||||
(&&&s)._sf_re_internal(&mut b).unwrap();
|
||||
(&&&&s)._sf_re_internal(&mut b).unwrap();
|
||||
Render::render_escaped(&s, &mut b).unwrap();
|
||||
Render::render_escaped(&s, &mut b).unwrap();
|
||||
Render::render_escaped(&&s, &mut b).unwrap();
|
||||
Render::render_escaped(&&&s, &mut b).unwrap();
|
||||
Render::render_escaped(&&&&s, &mut b).unwrap();
|
||||
assert_eq!(b.as_str(), "appleappleappleappleapple");
|
||||
b.clear();
|
||||
|
||||
(&'c')._sf_re_internal(&mut b).unwrap();
|
||||
(&&'<')._sf_re_internal(&mut b).unwrap();
|
||||
(&&&'&')._sf_re_internal(&mut b).unwrap();
|
||||
(&&&&' ')._sf_re_internal(&mut b).unwrap();
|
||||
Render::render_escaped(&'c', &mut b).unwrap();
|
||||
Render::render_escaped(&&'<', &mut b).unwrap();
|
||||
Render::render_escaped(&&&'&', &mut b).unwrap();
|
||||
Render::render_escaped(&&&&' ', &mut b).unwrap();
|
||||
assert_eq!(b.as_str(), "c<& ");
|
||||
b.clear();
|
||||
}
|
||||
|
@ -299,10 +394,10 @@ mod tests {
|
|||
use std::rc::Rc;
|
||||
|
||||
let mut b = Buffer::new();
|
||||
(&String::from("a"))._sf_r_internal(&mut b).unwrap();
|
||||
(&&PathBuf::from("b"))._sf_r_internal(&mut b).unwrap();
|
||||
(&Rc::new(4u32))._sf_re_internal(&mut b).unwrap();
|
||||
(&Rc::new(2.3f32))._sf_re_internal(&mut b).unwrap();
|
||||
Render::render(&String::from("a"), &mut b).unwrap();
|
||||
Render::render(&&PathBuf::from("b"), &mut b).unwrap();
|
||||
Render::render_escaped(&Rc::new(4u32), &mut b).unwrap();
|
||||
Render::render_escaped(&Rc::new(2.3f32), &mut b).unwrap();
|
||||
|
||||
assert_eq!(b.as_str(), "ab42.3");
|
||||
}
|
||||
|
@ -311,17 +406,17 @@ mod tests {
|
|||
fn float() {
|
||||
let mut b = Buffer::new();
|
||||
|
||||
(&0.0f64)._sf_re_internal(&mut b).unwrap();
|
||||
(&std::f64::INFINITY)._sf_re_internal(&mut b).unwrap();
|
||||
(&std::f64::NEG_INFINITY)._sf_re_internal(&mut b).unwrap();
|
||||
(&std::f64::NAN)._sf_re_internal(&mut b).unwrap();
|
||||
Render::render_escaped(&0.0f64, &mut b).unwrap();
|
||||
Render::render_escaped(&std::f64::INFINITY, &mut b).unwrap();
|
||||
Render::render_escaped(&std::f64::NEG_INFINITY, &mut b).unwrap();
|
||||
Render::render_escaped(&std::f64::NAN, &mut b).unwrap();
|
||||
assert_eq!(b.as_str(), "0.0inf-infNaN");
|
||||
b.clear();
|
||||
|
||||
(&0.0f32)._sf_re_internal(&mut b).unwrap();
|
||||
(&std::f32::INFINITY)._sf_re_internal(&mut b).unwrap();
|
||||
(&std::f32::NEG_INFINITY)._sf_re_internal(&mut b).unwrap();
|
||||
(&std::f32::NAN)._sf_re_internal(&mut b).unwrap();
|
||||
Render::render_escaped(&0.0f32, &mut b).unwrap();
|
||||
Render::render_escaped(&std::f32::INFINITY, &mut b).unwrap();
|
||||
Render::render_escaped(&std::f32::NEG_INFINITY, &mut b).unwrap();
|
||||
Render::render_escaped(&std::f32::NAN, &mut b).unwrap();
|
||||
assert_eq!(b.as_str(), "0.0inf-infNaN");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue