227 lines
7.8 KiB
Rust
227 lines
7.8 KiB
Rust
//! Rhai wrappers for Text module functions
|
|
//!
|
|
//! This module provides Rhai wrappers for the functions in the Text module.
|
|
|
|
use rhai::{Engine, EvalAltResult, Array, Map, Position};
|
|
use std::collections::HashMap;
|
|
use crate::text::{
|
|
TextReplacer, TextReplacerBuilder,
|
|
TemplateBuilder,
|
|
dedent, prefix,
|
|
name_fix, path_fix
|
|
};
|
|
|
|
/// Register Text module functions with the Rhai engine
|
|
///
|
|
/// # Arguments
|
|
///
|
|
/// * `engine` - The Rhai engine to register the functions with
|
|
///
|
|
/// # Returns
|
|
///
|
|
/// * `Result<(), Box<EvalAltResult>>` - Ok if registration was successful, Err otherwise
|
|
pub fn register_text_module(engine: &mut Engine) -> Result<(), Box<EvalAltResult>> {
|
|
// Register types
|
|
register_text_types(engine)?;
|
|
|
|
// Register TextReplacer constructor
|
|
engine.register_fn("text_replacer_new", text_replacer_new);
|
|
|
|
// Register TextReplacerBuilder instance methods
|
|
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);
|
|
|
|
// Register TextReplacer instance methods
|
|
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);
|
|
|
|
// Register TemplateBuilder constructor
|
|
engine.register_fn("template_builder_open", template_builder_open);
|
|
|
|
// Register TemplateBuilder instance methods
|
|
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);
|
|
|
|
// Register Fix functions directly from text module
|
|
engine.register_fn("name_fix", crate::text::name_fix);
|
|
engine.register_fn("path_fix", crate::text::path_fix);
|
|
|
|
// Register Dedent functions directly from text module
|
|
engine.register_fn("dedent", crate::text::dedent);
|
|
engine.register_fn("prefix", crate::text::prefix);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Register Text module types with the Rhai engine
|
|
fn register_text_types(engine: &mut Engine) -> Result<(), Box<EvalAltResult>> {
|
|
// Register TextReplacerBuilder type
|
|
engine.register_type_with_name::<TextReplacerBuilder>("TextReplacerBuilder");
|
|
|
|
// Register TextReplacer type
|
|
engine.register_type_with_name::<TextReplacer>("TextReplacer");
|
|
|
|
// Register TemplateBuilder type
|
|
engine.register_type_with_name::<TemplateBuilder>("TemplateBuilder");
|
|
|
|
Ok(())
|
|
}
|
|
|
|
// Helper functions for error conversion
|
|
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
|
|
))
|
|
})
|
|
}
|
|
|
|
// TextReplacer implementation
|
|
|
|
/// Creates a new TextReplacerBuilder
|
|
pub fn text_replacer_new() -> TextReplacerBuilder {
|
|
TextReplacerBuilder::default()
|
|
}
|
|
|
|
/// Sets the pattern to search for
|
|
pub fn pattern(builder: TextReplacerBuilder, pat: &str) -> TextReplacerBuilder {
|
|
builder.pattern(pat)
|
|
}
|
|
|
|
/// Sets the replacement text
|
|
pub fn replacement(builder: TextReplacerBuilder, rep: &str) -> TextReplacerBuilder {
|
|
builder.replacement(rep)
|
|
}
|
|
|
|
/// Sets whether to use regex
|
|
pub fn regex(builder: TextReplacerBuilder, yes: bool) -> TextReplacerBuilder {
|
|
builder.regex(yes)
|
|
}
|
|
|
|
/// Sets whether the replacement should be case-insensitive
|
|
pub fn case_insensitive(builder: TextReplacerBuilder, yes: bool) -> TextReplacerBuilder {
|
|
builder.case_insensitive(yes)
|
|
}
|
|
|
|
/// Adds another replacement operation to the chain and resets the builder for a new operation
|
|
pub fn and(builder: TextReplacerBuilder) -> TextReplacerBuilder {
|
|
builder.and()
|
|
}
|
|
|
|
/// Builds the TextReplacer with all configured replacement operations
|
|
pub fn build(builder: TextReplacerBuilder) -> Result<TextReplacer, Box<EvalAltResult>> {
|
|
string_error_to_rhai_error(builder.build())
|
|
}
|
|
|
|
/// Applies all configured replacement operations to the input text
|
|
pub fn replace(replacer: &mut TextReplacer, input: &str) -> String {
|
|
replacer.replace(input)
|
|
}
|
|
|
|
/// Reads a file, applies all replacements, and returns the result as a string
|
|
pub fn replace_file(replacer: &mut TextReplacer, path: &str) -> Result<String, Box<EvalAltResult>> {
|
|
io_error_to_rhai_error(replacer.replace_file(path))
|
|
}
|
|
|
|
/// Reads a file, applies all replacements, and writes the result back to the file
|
|
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))
|
|
}
|
|
|
|
/// Reads a file, applies all replacements, and writes the result to a new file
|
|
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))
|
|
}
|
|
|
|
// TemplateBuilder implementation
|
|
|
|
/// Creates a new TemplateBuilder with the specified template path
|
|
pub fn template_builder_open(template_path: &str) -> Result<TemplateBuilder, Box<EvalAltResult>> {
|
|
io_error_to_rhai_error(TemplateBuilder::open(template_path))
|
|
}
|
|
|
|
/// Adds a string variable to the template context
|
|
pub fn add_var_string(builder: TemplateBuilder, name: &str, value: &str) -> TemplateBuilder {
|
|
builder.add_var(name, value)
|
|
}
|
|
|
|
/// Adds an integer variable to the template context
|
|
pub fn add_var_int(builder: TemplateBuilder, name: &str, value: i64) -> TemplateBuilder {
|
|
builder.add_var(name, value)
|
|
}
|
|
|
|
/// Adds a float variable to the template context
|
|
pub fn add_var_float(builder: TemplateBuilder, name: &str, value: f64) -> TemplateBuilder {
|
|
builder.add_var(name, value)
|
|
}
|
|
|
|
/// Adds a boolean variable to the template context
|
|
pub fn add_var_bool(builder: TemplateBuilder, name: &str, value: bool) -> TemplateBuilder {
|
|
builder.add_var(name, value)
|
|
}
|
|
|
|
/// Adds an array variable to the template context
|
|
pub fn add_var_array(builder: TemplateBuilder, name: &str, array: Array) -> TemplateBuilder {
|
|
// Convert Rhai Array to Vec<String>
|
|
let vec: Vec<String> = array.iter()
|
|
.filter_map(|v| v.clone().into_string().ok())
|
|
.collect();
|
|
|
|
builder.add_var(name, vec)
|
|
}
|
|
|
|
/// Adds multiple variables to the template context from a Map
|
|
pub fn add_vars(builder: TemplateBuilder, vars: Map) -> TemplateBuilder {
|
|
// Convert Rhai Map to Rust HashMap
|
|
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);
|
|
}
|
|
}
|
|
|
|
// Add the variables
|
|
builder.add_vars(hash_map)
|
|
}
|
|
|
|
/// Renders the template with the current context
|
|
pub fn render(builder: &mut TemplateBuilder) -> Result<String, Box<EvalAltResult>> {
|
|
tera_error_to_rhai_error(builder.render())
|
|
}
|
|
|
|
/// Renders the template and writes the result to a file
|
|
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))
|
|
} |