use crate::{TemplateBuilder, TextReplacer, TextReplacerBuilder};
use rhai::{Array, Engine, EvalAltResult, Map, Position};
use std::collections::HashMap;
pub fn register_text_module(engine: &mut Engine) -> Result<(), Box<EvalAltResult>> {
register_text_types(engine)?;
engine.register_fn("text_replacer_new", text_replacer_new);
engine.register_fn("text_replacer_builder", text_replacer_new);
engine.register_fn("pattern", pattern);
engine.register_fn("replacement", replacement);
engine.register_fn("regex", regex);
engine.register_fn("case_insensitive", case_insensitive);
engine.register_fn("and", and);
engine.register_fn("build", build);
engine.register_fn("replace", replace);
engine.register_fn("replace_file", replace_file);
engine.register_fn("replace_file_in_place", replace_file_in_place);
engine.register_fn("replace_file_to", replace_file_to);
engine.register_fn("template_builder_open", template_builder_open);
engine.register_fn("add_var", add_var_string);
engine.register_fn("add_var", add_var_int);
engine.register_fn("add_var", add_var_float);
engine.register_fn("add_var", add_var_bool);
engine.register_fn("add_var", add_var_array);
engine.register_fn("add_vars", add_vars);
engine.register_fn("render", render);
engine.register_fn("render_to_file", render_to_file);
engine.register_fn("name_fix", crate::name_fix);
engine.register_fn("path_fix", crate::path_fix);
engine.register_fn("dedent", crate::dedent);
engine.register_fn("prefix", crate::prefix);
Ok(())
}
fn register_text_types(engine: &mut Engine) -> Result<(), Box<EvalAltResult>> {
engine.register_type_with_name::<TextReplacerBuilder>("TextReplacerBuilder");
engine.register_type_with_name::<TextReplacer>("TextReplacer");
engine.register_type_with_name::<TemplateBuilder>("TemplateBuilder");
Ok(())
}
fn io_error_to_rhai_error<T>(result: std::io::Result<T>) -> Result<T, Box<EvalAltResult>> {
result.map_err(|e| {
Box::new(EvalAltResult::ErrorRuntime(
format!("IO error: {}", e).into(),
Position::NONE,
))
})
}
fn tera_error_to_rhai_error<T>(result: Result<T, tera::Error>) -> Result<T, Box<EvalAltResult>> {
result.map_err(|e| {
Box::new(EvalAltResult::ErrorRuntime(
format!("Template error: {}", e).into(),
Position::NONE,
))
})
}
fn string_error_to_rhai_error<T>(result: Result<T, String>) -> Result<T, Box<EvalAltResult>> {
result.map_err(|e| Box::new(EvalAltResult::ErrorRuntime(e.into(), Position::NONE)))
}
pub fn text_replacer_new() -> TextReplacerBuilder {
TextReplacerBuilder::default()
}
pub fn pattern(builder: TextReplacerBuilder, pat: &str) -> TextReplacerBuilder {
builder.pattern(pat)
}
pub fn replacement(builder: TextReplacerBuilder, rep: &str) -> TextReplacerBuilder {
builder.replacement(rep)
}
pub fn regex(builder: TextReplacerBuilder, yes: bool) -> TextReplacerBuilder {
builder.regex(yes)
}
pub fn case_insensitive(builder: TextReplacerBuilder, yes: bool) -> TextReplacerBuilder {
builder.case_insensitive(yes)
}
pub fn and(builder: TextReplacerBuilder) -> TextReplacerBuilder {
builder.and()
}
pub fn build(builder: TextReplacerBuilder) -> Result<TextReplacer, Box<EvalAltResult>> {
string_error_to_rhai_error(builder.build())
}
pub fn replace(replacer: &mut TextReplacer, input: &str) -> String {
replacer.replace(input)
}
pub fn replace_file(replacer: &mut TextReplacer, path: &str) -> Result<String, Box<EvalAltResult>> {
io_error_to_rhai_error(replacer.replace_file(path))
}
pub fn replace_file_in_place(
replacer: &mut TextReplacer,
path: &str,
) -> Result<(), Box<EvalAltResult>> {
io_error_to_rhai_error(replacer.replace_file_in_place(path))
}
pub fn replace_file_to(
replacer: &mut TextReplacer,
input_path: &str,
output_path: &str,
) -> Result<(), Box<EvalAltResult>> {
io_error_to_rhai_error(replacer.replace_file_to(input_path, output_path))
}
pub fn template_builder_open(template_path: &str) -> Result<TemplateBuilder, Box<EvalAltResult>> {
io_error_to_rhai_error(TemplateBuilder::open(template_path))
}
pub fn add_var_string(builder: TemplateBuilder, name: &str, value: &str) -> TemplateBuilder {
builder.add_var(name, value)
}
pub fn add_var_int(builder: TemplateBuilder, name: &str, value: i64) -> TemplateBuilder {
builder.add_var(name, value)
}
pub fn add_var_float(builder: TemplateBuilder, name: &str, value: f64) -> TemplateBuilder {
builder.add_var(name, value)
}
pub fn add_var_bool(builder: TemplateBuilder, name: &str, value: bool) -> TemplateBuilder {
builder.add_var(name, value)
}
pub fn add_var_array(builder: TemplateBuilder, name: &str, array: Array) -> TemplateBuilder {
let vec: Vec<String> = array
.iter()
.filter_map(|v| v.clone().into_string().ok())
.collect();
builder.add_var(name, vec)
}
pub fn add_vars(builder: TemplateBuilder, vars: Map) -> TemplateBuilder {
let mut hash_map = HashMap::new();
for (key, value) in vars.iter() {
if let Ok(val_str) = value.clone().into_string() {
hash_map.insert(key.to_string(), val_str);
}
}
builder.add_vars(hash_map)
}
pub fn render(builder: &mut TemplateBuilder) -> Result<String, Box<EvalAltResult>> {
tera_error_to_rhai_error(builder.render())
}
pub fn render_to_file(
builder: &mut TemplateBuilder,
output_path: &str,
) -> Result<(), Box<EvalAltResult>> {
io_error_to_rhai_error(builder.render_to_file(output_path))
}