prmt/
executor.rs

1use crate::module_trait::ModuleContext;
2use crate::parser::{Token, parse};
3use crate::registry::ModuleRegistry;
4use crate::style::{ModuleStyle, AnsiStyle};
5
6pub fn render_template(
7    template: &str,
8    registry: &ModuleRegistry,
9    context: &ModuleContext,
10) -> Result<String, String> {
11    let mut output = String::new();
12    let tokens = parse(template);
13    
14    for token in tokens {
15        match token {
16            Token::Text(text) => {
17                output.push_str(&text);
18            }
19            Token::Placeholder(params) => {
20                let module = registry.get(&params.module)
21                    .ok_or_else(|| format!("Unknown module: {}", params.module))?;
22                
23                if let Some(text) = module.render(&params.format, context) {
24                    if !text.is_empty() {
25                        let mut result = String::new();
26                        result.push_str(&params.prefix);
27                        result.push_str(&text);
28                        result.push_str(&params.suffix);
29                        
30                        if !params.style.is_empty() {
31                            let style = AnsiStyle::parse(&params.style)
32                                .map_err(|e| format!("Style error for module '{}': {}", params.module, e))?;
33                            result = style.apply(&result);
34                        }
35                        
36                        output.push_str(&result);
37                    }
38                }
39            }
40        }
41    }
42    
43    Ok(output)
44}
45
46pub fn execute(
47    format_str: &str,
48    no_version: bool,
49    exit_code: Option<i32>,
50) -> Result<String, String> {
51    let context = ModuleContext {
52        no_version,
53        exit_code,
54    };
55    
56    let mut registry = ModuleRegistry::new();
57    register_builtin_modules(&mut registry);
58    
59    render_template(format_str, &registry, &context)
60}
61
62fn register_builtin_modules(registry: &mut ModuleRegistry) {
63    use crate::modules::*;
64    use std::sync::Arc;
65    
66    registry.register("path", Arc::new(path::PathModule::new()));
67    registry.register("git", Arc::new(git::GitModule::new()));
68    registry.register("ok", Arc::new(ok::OkModule::new()));
69    registry.register("fail", Arc::new(fail::FailModule::new()));
70    registry.register("rust", Arc::new(rust::RustModule::new()));
71    registry.register("node", Arc::new(node::NodeModule::new()));
72    registry.register("python", Arc::new(python::PythonModule::new()));
73    registry.register("go", Arc::new(go::GoModule::new()));
74    registry.register("deno", Arc::new(deno::DenoModule::new()));
75    registry.register("bun", Arc::new(bun::BunModule::new()))
76}