codegenr_lib/helpers/debug.rs
1use handlebars::HelperDef;
2use serde_json::{json, Value};
3
4pub const DEBUG: &str = "debug";
5pub const DEBUG_CTX: &str = "debug_ctx";
6
7/// A debug helper that output a json representation of input parameters
8/// ```
9/// # use codegenr_lib::helpers::*;
10/// # use serde_json::json;
11/// assert_eq!(
12/// exec_template(json!({"plop": "plop"}), "{{debug 42 \"42\" plop non_existing}}"),
13/// r#"
14/// [
15/// {
16/// "relative_path": "",
17/// "value": 42
18/// },
19/// {
20/// "relative_path": "",
21/// "value": "42"
22/// },
23/// {
24/// "relative_path": "plop",
25/// "value": "plop"
26/// },
27/// {
28/// "relative_path": "non_existing",
29/// "value": null
30/// }
31/// ]
32/// "#
33/// );
34/// ```
35pub struct DebugHelper;
36
37impl HelperDef for DebugHelper {
38 fn call<'reg: 'rc, 'rc>(
39 &self,
40 h: &handlebars::Helper<'reg, 'rc>,
41 _r: &'reg handlebars::Handlebars<'reg>,
42 _ctx: &'rc handlebars::Context,
43 _rc: &mut handlebars::RenderContext<'reg, 'rc>,
44 out: &mut dyn handlebars::Output,
45 ) -> handlebars::HelperResult {
46 let params: Vec<_> = h
47 .params()
48 .iter()
49 .map(|pj| {
50 json! ({
51 "relative_path": pj.relative_path().map(|s|s.to_owned()).unwrap_or_default(),
52 "value": pj.value(),
53 })
54 })
55 .collect();
56 let json = Value::Array(params);
57 let json = format!("{:#}", json);
58 out.write("\n")?;
59 out.write(&json)?;
60 out.write("\n")?;
61 Ok(())
62 }
63}
64
65/// Does not render anything but outputs the internal handlebars contexts to the commad line
66/// ```
67/// # use codegenr_lib::helpers::*;
68/// # use serde_json::json;
69///
70/// let _result = exec_template(json!({"plop": "plop"}), "{{debug_ctx 42 \"42\" plop non_existing}}");
71///
72/// // Couldn't have this test pass deterministically, but the result should be close to this
73/// // assert_eq!(
74/// // _result,
75/// // r#"helper:
76/// // Helper { name: "debug_ctx", params: [PathAndJson { relative_path: None, value: Constant(Number(42)) }, PathAndJson { relative_path: None, value: Constant(String("42")) }, PathAndJson { relative_path: Some("plop"), value: Context(String("plop"), ["plop"]) }, PathAndJson { relative_path: Some("non_existing"), value: Missing }], hash: {}, template: None, inverse: None, block_param: None, block: false }
77/// // handlebars:
78/// // Handlebars { templates: {"test": Template { name: Some("test"), elements: [Expression(HelperTemplate { name: Name("debug_ctx"), params: [Literal(Number(42)), Literal(String("42")), Path(Relative(([Named("plop")], "plop"))), Path(Relative(([Named("non_existing")], "non_existing")))], hash: {}, block_param: None, template: None, inverse: None, block: false })], mapping: [TemplateMapping(1, 1)] }}, helpers: ["lower_case", "trim_end", "split_get_last", "not", "start_with", "trim_block_end", "trim", "one_line", "if_array_contains", "no_empty_lines", "gte", "with", "lookup", "debug_ctx", "with_matching", "lte", "trim_start", "set", "with_set", "regex_extract", "if", "if_empty", "if_set", "trim_block_start", "log", "trim_block", "global_parameter", "gt", "upper_case", "len", "pascal_case", "ne", "debug", "camel_case", "clear", "lowercase_first_letter", "or", "unless", "if_equals", "get", "if_not_empty", "if_not_equals", "snake_case", "split_get_first", "hex", "uppercase_first_letter", "each", "and", "raw", "eq", "lt"], decorators: ["inline"], strict_mode: false, dev_mode: true }
79/// // context:
80/// // Context { data: Object({"plop": String("plop")}) }
81/// // render_context:
82/// // RenderContext { inner: RenderContextInner { partials: {}, partial_block_stack: [], root_template: Some("test"), current_template: Some("test"), disable_eacape: false }, blocks: [BlockContext { base_path: [], base_value: None, block_params: BlockParams { data: {} }, local_variables: LocalVars { first: None, last: None, index: None, key: None, extra: {} } }], modified_context: None }
83/// // "#
84/// //);
85/// ```
86pub struct DebugCtxHelper;
87
88impl HelperDef for DebugCtxHelper {
89 fn call<'reg: 'rc, 'rc>(
90 &self,
91 helper: &handlebars::Helper<'reg, 'rc>,
92 handlebars: &'reg handlebars::Handlebars<'reg>,
93 context: &'rc handlebars::Context,
94 render_context: &mut handlebars::RenderContext<'reg, 'rc>,
95 out: &mut dyn handlebars::Output,
96 ) -> handlebars::HelperResult {
97 out.write(&format!("helper:\n{:?}\n", helper))?;
98 out.write(&format!("handlebars:\n{:?}\n", handlebars))?;
99 out.write(&format!("context:\n{:?}\n", context))?;
100 out.write(&format!("render_context:\n{:?}\n", render_context))?;
101 Ok(())
102 }
103}