1use serde::Deserialize;
2use std::collections::HashMap;
3
4pub mod custom;
5pub(crate) mod filesystem;
6pub mod helpers;
7pub mod loader;
8pub mod processor;
9pub mod render;
10pub mod resolver;
11
12use filesystem::save_file_content;
13use handlebars::Handlebars;
14use loader::*;
15use render::*;
16use resolver::*;
17
18#[derive(Debug, Deserialize)]
19pub struct Options {
20 pub source: String,
21 pub output: String,
22 pub templates: Vec<String>,
23 pub intermediate: Option<String>,
24 pub custom_helpers: Vec<String>,
25 pub global_parameters: HashMap<String, serde_json::Value>,
26}
27
28pub fn run_codegenr(options: Options) -> Result<(), anyhow::Error> {
29 let document = DocumentPath::parse(&options.source)?;
30 let json = resolve_refs(document)?;
31
32 if options.intermediate.is_some() {
33 save_intermediate(&options.intermediate, "resolved.json", &format!("{:#}", json))?;
34 }
35
36 let mut all_templates = vec![];
37 for t in options.templates {
38 let templates = get_templates_from_directory(&t)?;
39 all_templates.extend(templates);
40 }
41 let templates = TemplateCollection::from_list(all_templates)?;
42
43 let mut handlebars = Handlebars::new();
44 helpers::handlebars_setup(&mut handlebars, options.global_parameters);
45 custom::handlebars_setup(&mut handlebars, options.custom_helpers)?;
46
47 let rendered = templates.render(&json, handlebars)?;
48
49 save_intermediate(&options.intermediate, "rendered.txt", &rendered)?;
50
51 processor::process(&rendered, options.output)
52}
53
54fn save_intermediate(file: &Option<String>, extension: &str, content: &str) -> Result<(), anyhow::Error> {
55 if let Some(s) = file {
56 let full_file_name = format!("{}.{}", s, extension);
57 save_file_content(".", &full_file_name, content)?;
58 }
59 Ok(())
60}