aoc_zen_runner/
codegen.rs1use std::fs::write;
2
3use anyhow::Result;
4use cargo_metadata::camino::Utf8Path;
5use liquid::ParserBuilder;
6use toml_edit::{value, Array, Document, Table};
7
8const YEAR_CARGO_TEMPLATE: &str = include_str!("templates/year-Cargo.toml");
9const GITIGNORE: &str = include_str!("templates/year-gitignore");
10pub fn populate_year_package(year_root: &Utf8Path, year_num: u32) -> Result<()> {
11 let parser = ParserBuilder::with_stdlib().build()?;
13 let cargo_template = parser.parse(YEAR_CARGO_TEMPLATE)?;
14
15 let cargo_args = liquid::object!({"year": year_num});
16 let cargo_rendered = cargo_template.render(&cargo_args)?;
17 write(year_root.join("Cargo.toml"), cargo_rendered.as_bytes())?;
18
19 write(year_root.join(".gitignore"), GITIGNORE.as_bytes())?;
21
22 Ok(())
23}
24
25pub fn add_package_to_workspace(workspace_toml: &Utf8Path, year_num: u32) -> Result<()> {
26 let mut doc = std::fs::read_to_string(workspace_toml)?.parse::<Document>()?;
28
29 let members: &mut Array = doc["workspace"]["members"]
30 .as_array_mut()
31 .expect("Cargo doc format not recognized");
32
33 members.push(&year_num.to_string());
34
35 std::fs::write(workspace_toml, doc.to_string().as_bytes())?;
36
37 Ok(())
38}
39
40const DAY_RS: &str = include_str!("templates/dayX.rs");
41pub fn generate_day_file(day_file: &Utf8Path, year_num: u32, day_num: u32) -> Result<()> {
42 let parser = ParserBuilder::with_stdlib().build()?;
44 let rs_template = parser.parse(DAY_RS)?;
45
46 let rs_args = liquid::object!({"year": year_num, "day": day_num});
47 let rs_rendered = rs_template.render(&rs_args)?;
48
49 write(day_file, rs_rendered.as_bytes())?;
50
51 Ok(())
52}
53
54pub fn add_day_to_package(
55 day_num: u32,
56 year_num: u32,
57 day_file: &Utf8Path,
58 year_cargo: &Utf8Path,
59 year_path: &Utf8Path,
60) -> Result<()> {
61 let mut doc = std::fs::read_to_string(year_cargo)?.parse::<Document>()?;
63 let bintable = doc["bin"]
64 .as_array_of_tables_mut()
65 .expect("Per-year cargo doc should have already had a [[bin]] table in it.");
66
67 let mut new_table = Table::new();
68 new_table["name"] = value(format!("{}-day{}", year_num, day_num));
69
70 let partial_path = day_file.as_str().replace(year_path.as_str(), "");
71 let partial_path = partial_path.trim_start_matches("/");
72
73 new_table["path"] = value(partial_path);
74
75 bintable.push(new_table);
76
77 write(year_cargo, doc.to_string().as_bytes())?;
78
79 Ok(())
80}