-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild.rs
111 lines (97 loc) · 2.74 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
use std::{
env,
error::Error,
fs::{self, File},
io,
};
fn main() -> Result<(), Box<dyn Error>> {
let crate_dir = env::var("CARGO_MANIFEST_DIR")?;
let out_dir = env::var("OUT_DIR")?;
let path = format!("{out_dir}/days.rs");
let mut output = File::create(path)?;
let solutions = find_solutions("src")?.collect::<Vec<_>>();
write_module_declarations(&solutions, &mut output, &crate_dir)?;
write_solve_function(&solutions, &mut output)?;
Ok(())
}
enum Solution {
Rust {
file_name: String,
module_name: String,
},
Prolog {
file_name: String,
path: String,
},
}
fn find_solutions(src_dir: &str) -> io::Result<impl Iterator<Item = Solution>> {
Ok(fs::read_dir(src_dir)?.filter_map(|file| {
let os_file_name = file.ok()?.file_name();
let file_name = os_file_name.to_str()?;
if !file_name.starts_with("day_") {
return None;
}
if let Some(module_name) = file_name.strip_suffix(".rs") {
Some(Solution::Rust {
file_name: file_name.to_owned(),
module_name: module_name.to_owned(),
})
} else if file_name.ends_with(".pl") {
Some(Solution::Prolog {
file_name: file_name.to_owned(),
path: format!("src/{file_name}"),
})
} else {
None
}
}))
}
fn write_module_declarations<'a>(
solutions: impl IntoIterator<Item = &'a Solution>,
output: &mut dyn io::Write,
crate_dir: &str,
) -> io::Result<()> {
for solution in solutions {
if let Solution::Rust {
file_name,
module_name,
} = solution
{
writeln!(
output,
r#"#[path = "{crate_dir}/src/{file_name}"] mod {module_name};"#
)?;
}
}
Ok(())
}
fn write_solve_function<'a>(
solutions: impl IntoIterator<Item = &'a Solution>,
output: &mut dyn io::Write,
) -> io::Result<()> {
writeln!(
output,
"fn solve(solution_file_name: &str, input_path: &str) {{
match solution_file_name {{"
)?;
for solution in solutions {
match solution {
Solution::Rust {
file_name,
module_name,
} => writeln!(
output,
"{file_name:?} => run_rust({module_name}::solve, input_path),"
)?,
Solution::Prolog { file_name, path } => writeln!(
output,
"{file_name:?} => run_prolog({path:?}, input_path),"
)?,
}
}
writeln!(
output,
r#"_ => panic!("no such solution: {{solution_file_name}}") }} }}"#
)?;
Ok(())
}