fluent_handlebars_runtime/
helper.rs1use std::collections::HashMap;
2
3use fluent_templates::Loader;
4use fluent_templates::fluent_bundle::FluentValue;
5use handlebars::{Context, Handlebars, Helper, HelperDef, HelperResult, Output, RenderContext, RenderError};
6use serde_json::Value as Json;
7
8pub struct FluentHandlebars<L: Loader + Send + Sync>{
13 loader: L
14}
15
16impl<L: Loader + Send + Sync> FluentHandlebars<L> {
17 pub fn new(ldr: L) -> FluentHandlebars<L> {
18 FluentHandlebars {
19 loader: ldr
20 }
21 }
22}
23
24impl<L: Loader + Send + Sync> HelperDef for FluentHandlebars<L> {
25 fn call<'reg: 'rc, 'rc>(
26 &self,
27 helper: &Helper<'reg, 'rc>,
28 _reg: &'reg Handlebars,
29 context: &'rc Context,
30 _rcx: &mut RenderContext<'reg, 'rc>,
31 out: &mut dyn Output,
32 ) -> HelperResult {
33 let id = if let Some(id) = helper.param(0) {
34 id
35 } else {
36 return Err(RenderError::new(
37 "{{t}} must have at least one parameter",
38 ));
39 };
40
41 if id.relative_path().is_some() {
42 return Err(RenderError::new(
43 "{{t}} takes a string literal, not a path",
44 ));
45 }
46
47 let id = if let Json::String(ref s) = *id.value() {
48 s
49 } else {
50 return Err(RenderError::new("{{t}} takes a string parameter"));
51 };
52
53 let args: Option<HashMap<String, FluentValue>> = if !context.data().is_object() {
54 None
55 } else {
56 let map = context
57 .data()
58 .as_object().unwrap()
59 .iter()
60 .filter_map(|(k, v)| {
61 let val: FluentValue = match v {
62 Json::Number(n) => n.as_f64().unwrap().into(),
66 Json::String(s) => s.to_owned().into(),
67 _ => return None,
68 };
69 Some((k.to_string(), val))
70 })
71 .collect();
72 Some(map)
73 };
74
75 let lang = context
76 .data()
77 .get("lang")
78 .expect("Language not set in context")
79 .as_str()
80 .expect("Language must be string")
81 .parse()
82 .expect("Language not valid identifier");
83
84 let response = self.loader.lookup_complete(&lang, &id, args.as_ref());
85 out.write(&response).map_err(
86 |e| RenderError::from_error("fluent-handlebars-runtime helper", e)
87 )
88 }
89}