use handlebars::{Context, Handlebars, Helper, HelperResult, JsonRender, Output, RenderContext, RenderErrorReason}; use serde_json::{Map, Value}; use std::{env, error::Error}; use std::fs; use url_escape; fn main() -> Result<(), Box> { let mut handlebars = Handlebars::new(); let path_to_contents = env::args().nth(1).expect("The first argument to be present."); let output_path = env::args().nth(2).expect("The second argument to be present."); let contents = fs::read_to_string(path_to_contents).expect("To be able to open a file at the path passed as the first argument."); let secret_inputs = env::vars().filter(|(key, _)| key.starts_with("SECRET_")); let mut data_map = Map::new(); for (_, value) in secret_inputs { let Some((secret_key, path_to_secret)) = value.split_once(":") else { panic!("Secret environment variable is not in format 'name:path_to_secret'"); }; let secret_value = fs::read_to_string(path_to_secret)?; println!("Registering secret '{secret_key}' from '{path_to_secret}'."); data_map.insert(secret_key.to_string(), Value::String(secret_value.trim().to_string())); } handlebars.register_helper("uri_encode_user_info",Box::new(|helper: &Helper, _: &Handlebars, _: &Context, _: &mut RenderContext, out: &mut dyn Output| -> HelperResult { let parameter = helper.param(0).ok_or(RenderErrorReason::ParamNotFoundForIndex("uri_encode_user_info", 0))?; let parameter_value = parameter.value().render(); out.write(url_escape::encode_userinfo_to_string(parameter_value, &mut String::from("https://")))?; Ok(()) })); handlebars.register_helper("uri_encode_path",Box::new(|helper: &Helper, _: &Handlebars, _: &Context, _: &mut RenderContext, out: &mut dyn Output| -> HelperResult { let parameter = helper.param(0).ok_or(RenderErrorReason::ParamNotFoundForIndex("uri_encode_path", 0))?; let parameter_value = parameter.value().render(); out.write(url_escape::encode_path_to_string(parameter_value, &mut String::from("https://")))?; Ok(()) })); handlebars.register_helper("uri_encode_component",Box::new(|helper: &Helper, _: &Handlebars, _: &Context, _: &mut RenderContext, out: &mut dyn Output| -> HelperResult { let parameter = helper.param(0).ok_or(RenderErrorReason::ParamNotFoundForIndex("uri_encode_component", 0))?; let parameter_value = parameter.value().render(); out.write(url_escape::encode_component_to_string(parameter_value, &mut String::from("https://")))?; Ok(()) })); handlebars.register_helper("json_encode_string",Box::new(|helper: &Helper, _: &Handlebars, _: &Context, _: &mut RenderContext, out: &mut dyn Output| -> HelperResult { let parameter = helper.param(0).ok_or(RenderErrorReason::ParamNotFoundForIndex("json_encode_string", 0))?; let parameter_value = parameter.value().render(); let encoded = serde_json::Value::String(parameter_value).to_string(); let encoded = encoded.strip_prefix('"').unwrap().strip_suffix('"').unwrap(); out.write(encoded)?; Ok(()) })); // NOTE: By default, handlebars escapes variables for HTML. handlebars.register_escape_fn(handlebars::no_escape); let output = handlebars.render_template(contents.as_str(), &Value::Object(data_map))?; fs::write(output_path, output)?; Ok(()) }