-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild.rs
130 lines (111 loc) · 4.4 KB
/
build.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
use regex::Regex;
use std::{
collections::HashMap,
env, fs,
io::{Read, Write},
};
fn main() {
// Output file paths
let out_dir = env::var("OUT_DIR").unwrap();
let main_day_list_path = out_dir.clone() + "/main_day_list.gen.rs";
let divan_day_list_path = out_dir.clone() + "/divan_day_list.gen.rs";
let criterion_day_list_path = out_dir + "/criterion_day_list.gen.rs";
// Source paths
let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let src_dir = manifest_dir + "/src";
// Regex matches for source files and directories
let years_dir_re: Regex = Regex::new(r"aoc\d+$").unwrap();
let day_source_re: Regex = Regex::new(r"day\d{2}_(0|1).rs$").unwrap();
// Find year directories within src
let src_dir_reader = fs::read_dir(src_dir.clone()).unwrap();
let mut years = HashMap::new();
for f in src_dir_reader {
let entry = f.unwrap();
let path = entry.path();
if !path.is_dir() {
continue;
}
let path_str = path.to_string_lossy().to_string();
if years_dir_re.is_match(&path_str) {
years.entry(path).or_insert(Vec::new());
}
}
// Find day files within each year directory
for (year_path, days) in &mut years {
let year_dir_reader = fs::read_dir(year_path).unwrap();
for f in year_dir_reader {
let entry = f.unwrap();
let path = entry.path();
if !path.is_file() {
continue;
}
let path_str = path.to_string_lossy().to_string();
if day_source_re.is_match(&path_str) {
days.push(path);
}
}
}
// Form strings that can later be used in source files
// Note that some are constructed to be a single block with {}
let mut main_day_list = String::from("{\n");
let mut divan_day_list = String::new();
let mut criterion_day_list = String::from("{\n");
let mut year_lib_map = HashMap::new();
for (year_path, days) in years {
let year = year_path.file_name().unwrap().to_string_lossy().to_string();
let mut days: Vec<_> = days
.iter()
.map(|d| {
d.file_name()
.unwrap()
.to_string_lossy()
.strip_suffix(".rs")
.unwrap()
.to_string()
})
.collect();
days.sort();
let mut year_lib_list = String::from("// Auto generated, no need to edit\n");
for day in days {
main_day_list.push_str(&format!("process_day!({year}::{day}, args, results);\n"));
divan_day_list.push_str(&format!(
"#[divan::bench]\
fn {year}_{day}() {{ let _ = divian::black_box({year}::{day}::day()); }} \n"
));
criterion_day_list.push_str(&format!(
"_c.bench_function(\"{year}::{day}\", |b| b.iter(&mut {year}::{day}::day));\n"
));
year_lib_list.push_str(&format!("pub mod {day};\n"));
}
year_lib_map.entry(year).or_insert(year_lib_list);
}
main_day_list.push('}');
criterion_day_list.push('}');
// Write out files to be included
let mut main_day_list_file = fs::File::create(main_day_list_path).unwrap();
main_day_list_file
.write_all(main_day_list.as_bytes())
.unwrap();
let mut divan_day_list_file = fs::File::create(divan_day_list_path).unwrap();
divan_day_list_file
.write_all(divan_day_list.as_bytes())
.unwrap();
let mut criterion_day_list_file = fs::File::create(criterion_day_list_path).unwrap();
criterion_day_list_file
.write_all(criterion_day_list.as_bytes())
.unwrap();
for (year, content) in year_lib_map {
let year_lib_path = format!("{src_dir}/{year}.rs");
// Some auto running checkers could endlessly loop if we always overwrite this file so read
// it first to see if changes need to be made
if let Ok(mut year_lib_file) = fs::File::open(&year_lib_path) {
let mut current_content = String::new();
year_lib_file.read_to_string(&mut current_content).unwrap();
if current_content == content {
continue;
}
}
let mut year_lib_file = fs::File::create(year_lib_path).unwrap();
year_lib_file.write_all(content.as_bytes()).unwrap();
}
}