1use crate::context::Context;
2use crate::decorators::{DecoratorDef, DecoratorResult};
3use crate::error::RenderError;
4use crate::registry::Registry;
5use crate::render::{Decorator, RenderContext};
6
7#[derive(Clone, Copy)]
8pub struct InlineDecorator;
9
10fn get_name<'reg: 'rc, 'rc>(d: &Decorator<'reg, 'rc>) -> Result<String, RenderError> {
11 d.param(0)
12 .ok_or_else(|| RenderError::new("Param required for decorator \"inline\""))
13 .and_then(|v: &PathAndJson<'_, '_>| {
14 v.value()
15 .as_str()
16 .map(|v| v.to_owned())
17 .ok_or_else(|| RenderError::new(desc:"inline name must be string"))
18 })
19}
20
21impl DecoratorDef for InlineDecorator {
22 fn call<'reg: 'rc, 'rc>(
23 &self,
24 d: &Decorator<'reg, 'rc>,
25 _: &'reg Registry<'reg>,
26 _: &'rc Context,
27 rc: &mut RenderContext<'reg, 'rc>,
28 ) -> DecoratorResult {
29 let name: String = get_name(d)?;
30
31 let template: &Template = d
32 .template()
33 .ok_or_else(|| RenderError::new(desc:"inline should have a block"))?;
34
35 rc.set_partial(name, partial:template);
36 Ok(())
37 }
38}
39
40pub static INLINE_DECORATOR: InlineDecorator = InlineDecorator;
41
42#[cfg(test)]
43mod test {
44 use crate::context::Context;
45 use crate::registry::Registry;
46 use crate::render::{Evaluable, RenderContext};
47 use crate::template::Template;
48
49 #[test]
50 fn test_inline() {
51 let t0 =
52 Template::compile("{{#*inline \"hello\"}}the hello world inline partial.{{/inline}}")
53 .ok()
54 .unwrap();
55
56 let hbs = Registry::new();
57
58 let ctx = Context::null();
59 let mut rc = RenderContext::new(None);
60 t0.elements[0].eval(&hbs, &ctx, &mut rc).unwrap();
61
62 assert!(rc.get_partial(&"hello".to_owned()).is_some());
63 }
64}
65