From 0f55aebf5d8171e930a09777dc5e15989f06f21c Mon Sep 17 00:00:00 2001 From: Adolph C Date: Sat, 26 Sep 2020 17:10:09 -0400 Subject: [PATCH 1/3] Added `register_local_helper_rc` to `RenderContext`. --- src/render.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/render.rs b/src/render.rs index 18b2afd67..0aaa3f1ee 100644 --- a/src/render.rs +++ b/src/render.rs @@ -199,6 +199,18 @@ impl<'reg: 'rc, 'rc> RenderContext<'reg, 'rc> { .insert(name.to_string(), def.into()) } + /// Register a reference counted helper in this render context. + /// + /// If there was a local helper with the same name present, it will be replaced + /// with the new local helper and returned, otherwise this will return `None`. + pub fn register_local_helper_rc( + &mut self, + name: &str, + def: Rc, + ) -> Option> { + self.inner_mut().local_helpers.insert(name.to_string(), def) + } + /// Remove a helper from render context pub fn unregister_local_helper(&mut self, name: &str) { self.inner_mut().local_helpers.remove(name); From a38413d67cab0a11494596b757cf244061d07b83 Mon Sep 17 00:00:00 2001 From: Adolph C Date: Thu, 1 Oct 2020 16:27:29 -0400 Subject: [PATCH 2/3] Make `RenderContext::register_local_helper` generic. Also implemented `HelperDef` directly on Rc's and Arc's so that they can be passed directly into `register_local_helper`. With this change we can call `register_local_helper(helper)` instead of `register_local_helper(Box::new(helper))`. --- src/helpers/mod.rs | 32 ++++++++++++++++++++++++++++++++ src/render.rs | 23 +++++++---------------- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/src/helpers/mod.rs b/src/helpers/mod.rs index 8d1c2d7d6..e2ba66d89 100644 --- a/src/helpers/mod.rs +++ b/src/helpers/mod.rs @@ -131,6 +131,38 @@ impl< } } +impl HelperDef for std::rc::Rc +where + T: HelperDef, +{ + fn call<'reg: 'rc, 'rc>( + &self, + h: &Helper<'reg, 'rc>, + r: &'reg Registry<'reg>, + ctx: &'rc Context, + rc: &mut RenderContext<'reg, 'rc>, + out: &mut dyn Output, + ) -> HelperResult { + (**self).call(h, r, ctx, rc, out) + } +} + +impl HelperDef for std::sync::Arc +where + T: HelperDef, +{ + fn call<'reg: 'rc, 'rc>( + &self, + h: &Helper<'reg, 'rc>, + r: &'reg Registry<'reg>, + ctx: &'rc Context, + rc: &mut RenderContext<'reg, 'rc>, + out: &mut dyn Output, + ) -> HelperResult { + (**self).call(h, r, ctx, rc, out) + } +} + mod block_util; pub(crate) mod helper_boolean; mod helper_each; diff --git a/src/render.rs b/src/render.rs index 0aaa3f1ee..717f07b06 100644 --- a/src/render.rs +++ b/src/render.rs @@ -189,26 +189,17 @@ impl<'reg: 'rc, 'rc> RenderContext<'reg, 'rc> { /// Register a helper in this render context. /// This is a feature provided by Decorator where you can create /// temporary helpers. - pub fn register_local_helper( + pub fn register_local_helper( &mut self, name: &str, - def: Box, - ) -> Option> { + def: H, + ) -> Option> + where + H: HelperDef + 'rc, + { self.inner_mut() .local_helpers - .insert(name.to_string(), def.into()) - } - - /// Register a reference counted helper in this render context. - /// - /// If there was a local helper with the same name present, it will be replaced - /// with the new local helper and returned, otherwise this will return `None`. - pub fn register_local_helper_rc( - &mut self, - name: &str, - def: Rc, - ) -> Option> { - self.inner_mut().local_helpers.insert(name.to_string(), def) + .insert(name.to_string(), Rc::from(def)) } /// Remove a helper from render context From f7292d7ae7d8536d1e06bec12f0eb91d0dab23b4 Mon Sep 17 00:00:00 2001 From: Adolph C Date: Thu, 1 Oct 2020 16:31:50 -0400 Subject: [PATCH 3/3] Simplify `register_local_helper` calls in tests and examples. --- examples/decorator.rs | 28 +++++++++++++--------------- src/decorators/mod.rs | 4 ++-- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/examples/decorator.rs b/examples/decorator.rs index 81aa6fe8d..f406857fe 100644 --- a/examples/decorator.rs +++ b/examples/decorator.rs @@ -41,21 +41,19 @@ fn format_decorator( .unwrap_or("".to_owned()); rc.register_local_helper( "format", - Box::new( - move |h: &Helper, - _: &Handlebars, - _: &Context, - _: &mut RenderContext, - out: &mut dyn Output| { - // get parameter from helper or throw an error - let param = h - .param(0) - .ok_or(RenderError::new("Param 0 is required for format helper."))?; - let rendered = format!("{} {}", param.value().render(), suffix); - out.write(rendered.as_ref())?; - Ok(()) - }, - ), + move |h: &Helper, + _: &Handlebars, + _: &Context, + _: &mut RenderContext, + out: &mut dyn Output| { + // get parameter from helper or throw an error + let param = h + .param(0) + .ok_or(RenderError::new("Param 0 is required for format helper."))?; + let rendered = format!("{} {}", param.value().render(), suffix); + out.write(rendered.as_ref())?; + Ok(()) + }, ); Ok(()) } diff --git a/src/decorators/mod.rs b/src/decorators/mod.rs index b8bad900f..b49003012 100644 --- a/src/decorators/mod.rs +++ b/src/decorators/mod.rs @@ -51,7 +51,7 @@ pub type DecoratorResult = Result<(), RenderError>; /// // your helper logic /// Ok(()) /// }; -/// rc.register_local_helper("distance", Box::new(new_helper)); +/// rc.register_local_helper("distance", new_helper); /// Ok(()) /// } /// ``` @@ -274,7 +274,7 @@ mod test { Ok(()) }; - rc.register_local_helper("distance", Box::new(new_helper)); + rc.register_local_helper("distance", new_helper); Ok(()) }, ),