From 19a740f26c85fe4192e80ae88c0a60cf6f8dca8a Mon Sep 17 00:00:00 2001 From: Michael Pfaff Date: Thu, 14 Mar 2024 23:01:39 -0400 Subject: [PATCH] impl RenderOnce on tuples of up to 8 values --- sailfish/src/runtime/render.rs | 68 ++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 4 deletions(-) diff --git a/sailfish/src/runtime/render.rs b/sailfish/src/runtime/render.rs index 8c727b0..c58effe 100644 --- a/sailfish/src/runtime/render.rs +++ b/sailfish/src/runtime/render.rs @@ -131,10 +131,7 @@ pub trait RenderOnce: Sized { // } // } -impl RenderOnce for T -where - T: Render, -{ +impl RenderOnce for T { #[inline] fn render_once(self, b: &mut Buffer) -> Result<(), RenderError> { self.render(b) @@ -459,6 +456,69 @@ impl Render for Wrapping { } } +macro_rules! render_tuple { + ($A:ident) => { + render_tuple!(@ $A); + }; + ($A:ident $(, $T:ident)+) => { + render_tuple!(@ $A $(, $T)+); + render_tuple!($($T),+); + }; + (@ $($T:ident),*) => { + impl<$($T: Render),+> Render for ($($T,)+) { + #[inline] + fn render(&self, b: &mut Buffer) -> Result<(), RenderError> { + #[allow(non_snake_case)] + let ($($T,)+) = self; + $($T.render(b)?;)+ + Ok(()) + } + + #[inline] + fn render_escaped(&self, b: &mut Buffer) -> Result<(), RenderError> { + #[allow(non_snake_case)] + let ($($T,)+) = self; + $($T.render_escaped(b)?;)+ + Ok(()) + } + } + }; +} + +macro_rules! render_once_tuple { + ($A:ident) => { + render_once_tuple!(@ $A); + }; + ($A:ident $(, $T:ident)+) => { + render_once_tuple!(@ $A $(, $T)+); + render_once_tuple!($($T),+); + }; + (@ $($T:ident),*) => { + impl<$($T: RenderOnce),+> RenderOnce for ($($T,)+) { + #[inline] + fn render_once(self, b: &mut Buffer) -> Result<(), RenderError> { + #[allow(non_snake_case)] + let ($($T,)+) = self; + $($T.render_once(b)?;)+ + Ok(()) + } + + #[inline] + fn render_once_escaped(self, b: &mut Buffer) -> Result<(), RenderError> { + #[allow(non_snake_case)] + let ($($T,)+) = self; + $($T.render_once_escaped(b)?;)+ + Ok(()) + } + } + }; +} + +// TODO: figure out how to use specialization to allow a Render impl on tuples, if possible. If +// not, oh well, it can be worked around. +// render_tuple!(A, B, C, D, E, F, G, H); +render_once_tuple!(A, B, C, D, E, F, G, H); + /// The error type which is returned from template function #[derive(Clone, Debug)] pub enum RenderError {