Move solutions from bin into lib.
The files src/bin/01.rs, 02.rs, etc are still created by scaffold, but they now call the solution in the src/day01.rs, src/day02.rs, thereby allowing benchmarking. This means that scaffold also updates lib.rs to add the module definitions. Right now this is done using a simple replace of "// pub mod day01;" with "pub mod day01;". There is a probably a nicer way to do this, but it works. Also due to an issue in cargo we need to run "cargo clean -p advent_of_code". Otherwise "cargo check" will fail. See https://github.com/rust-lang/cargo/issues/6529
This commit is contained in:
parent
6ae29a25e8
commit
e601d48d16
2 changed files with 134 additions and 17 deletions
|
@ -4,11 +4,11 @@
|
||||||
*/
|
*/
|
||||||
use std::{
|
use std::{
|
||||||
fs::{File, OpenOptions},
|
fs::{File, OpenOptions},
|
||||||
io::Write,
|
io::{Error, Read, Seek, Write},
|
||||||
process,
|
process::{self, Command},
|
||||||
};
|
};
|
||||||
|
|
||||||
const MODULE_TEMPLATE: &str = r###"pub fn part_one(input: &str) -> Option<u32> {
|
const MODULE_LIB_TEMPLATE: &str = r###"pub fn part_one(input: &str) -> Option<u32> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,30 +16,33 @@ pub fn part_two(input: &str) -> Option<u32> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let input = &advent_of_code::read_file("inputs", DAY);
|
|
||||||
advent_of_code::solve!(1, part_one, input);
|
|
||||||
advent_of_code::solve!(2, part_two, input);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_part_one() {
|
fn test_part_one() {
|
||||||
let input = advent_of_code::read_file("examples", DAY);
|
let input = crate::read_file("examples", DAY);
|
||||||
assert_eq!(part_one(&input), None);
|
assert_eq!(part_one(&input), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_part_two() {
|
fn test_part_two() {
|
||||||
let input = advent_of_code::read_file("examples", DAY);
|
let input = crate::read_file("examples", DAY);
|
||||||
assert_eq!(part_two(&input), None);
|
assert_eq!(part_two(&input), None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"###;
|
"###;
|
||||||
|
|
||||||
|
const MODULE_BIN_TEMPLATE: &str = r###"use advent_of_code::dayDAYPAD::{part_one, part_two};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let input = &advent_of_code::read_file("inputs", DAY);
|
||||||
|
advent_of_code::solve!(1, part_one, input);
|
||||||
|
advent_of_code::solve!(2, part_two, input);
|
||||||
|
}
|
||||||
|
"###;
|
||||||
|
|
||||||
fn parse_args() -> Result<u8, pico_args::Error> {
|
fn parse_args() -> Result<u8, pico_args::Error> {
|
||||||
let mut args = pico_args::Arguments::from_env();
|
let mut args = pico_args::Arguments::from_env();
|
||||||
args.free_from_str()
|
args.free_from_str()
|
||||||
|
@ -53,6 +56,46 @@ fn create_file(path: &str) -> Result<File, std::io::Error> {
|
||||||
OpenOptions::new().write(true).create(true).open(path)
|
OpenOptions::new().write(true).create(true).open(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn modify_lib(day: u8) -> Result<(), Error> {
|
||||||
|
let lib_path = "src/lib.rs";
|
||||||
|
|
||||||
|
let mut file = OpenOptions::new()
|
||||||
|
.read(true)
|
||||||
|
.write(true)
|
||||||
|
.create(false)
|
||||||
|
.open(lib_path)?;
|
||||||
|
|
||||||
|
let mut old_code = String::new();
|
||||||
|
file.read_to_string(&mut old_code)?;
|
||||||
|
|
||||||
|
file.rewind()?;
|
||||||
|
file.set_len(0)?;
|
||||||
|
|
||||||
|
match file.write_all(
|
||||||
|
old_code
|
||||||
|
.replace(
|
||||||
|
&format!("// pub mod day{:02};", day),
|
||||||
|
&format!("pub mod day{:02};", day),
|
||||||
|
)
|
||||||
|
.as_bytes(),
|
||||||
|
) {
|
||||||
|
Ok(_) => {
|
||||||
|
println!("Updated lib.rs to include 'day{:02}' module", day);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!(
|
||||||
|
"Failed to write updateded lib.rs to include 'day{:02}' module: {}",
|
||||||
|
day, e
|
||||||
|
);
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
file.flush()?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let day = match parse_args() {
|
let day = match parse_args() {
|
||||||
Ok(day) => day,
|
Ok(day) => day,
|
||||||
|
@ -66,22 +109,59 @@ fn main() {
|
||||||
|
|
||||||
let input_path = format!("src/inputs/{}.txt", day_padded);
|
let input_path = format!("src/inputs/{}.txt", day_padded);
|
||||||
let example_path = format!("src/examples/{}.txt", day_padded);
|
let example_path = format!("src/examples/{}.txt", day_padded);
|
||||||
let module_path = format!("src/bin/{}.rs", day_padded);
|
let module_bin_path = format!("src/bin/{}.rs", day_padded);
|
||||||
|
let module_lib_path = format!("src/day{}.rs", day_padded);
|
||||||
|
|
||||||
let mut file = match safe_create_file(&module_path) {
|
match modify_lib(day) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Failed to update lib.rs file: {}", e);
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut bin_file = match safe_create_file(&module_bin_path) {
|
||||||
Ok(file) => file,
|
Ok(file) => file,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("Failed to create module file: {}", e);
|
eprintln!("Failed to create module bin file: {}", e);
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match file.write_all(MODULE_TEMPLATE.replace("DAY", &day.to_string()).as_bytes()) {
|
match bin_file.write_all(
|
||||||
|
MODULE_BIN_TEMPLATE
|
||||||
|
.replace("DAYPAD", &day_padded)
|
||||||
|
.replace("DAY", &day.to_string())
|
||||||
|
.as_bytes(),
|
||||||
|
) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
println!("Created module file \"{}\"", &module_path);
|
println!("Created module bin file \"{}\"", &module_bin_path);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("Failed to write module contents: {}", e);
|
eprintln!("Failed to write bin module contents: {}", e);
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut lib_file = match safe_create_file(&module_lib_path) {
|
||||||
|
Ok(file) => file,
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Failed to create module lib file: {}", e);
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match lib_file.write_all(
|
||||||
|
MODULE_LIB_TEMPLATE
|
||||||
|
.replace("DAYPAD", &day_padded)
|
||||||
|
.replace("DAY", &day.to_string())
|
||||||
|
.as_bytes(),
|
||||||
|
) {
|
||||||
|
Ok(_) => {
|
||||||
|
println!("Created module lib file \"{}\"", &module_bin_path);
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Failed to write lib module contents: {}", e);
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,6 +186,17 @@ fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We need to execute cargo clean -p advent_of_code otherwise there can be cache issues when executing cargo check
|
||||||
|
// As far as I can tell this relates to https://github.com/rust-lang/cargo/issues/6529
|
||||||
|
let clean_output = Command::new("cargo")
|
||||||
|
.args(["clean", "-p", "advent_of_code"])
|
||||||
|
.output()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
if !clean_output.status.success() {
|
||||||
|
eprint!("Failed to execute 'cargo clean -p advent_of_code'.");
|
||||||
|
}
|
||||||
|
|
||||||
println!("---");
|
println!("---");
|
||||||
println!(
|
println!(
|
||||||
"🎄 Type `cargo solve {}` to run your solution.",
|
"🎄 Type `cargo solve {}` to run your solution.",
|
||||||
|
|
26
src/lib.rs
26
src/lib.rs
|
@ -6,6 +6,32 @@
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
|
// modules for the different days are automatically uncomented by the scaffold command
|
||||||
|
pub mod day01;
|
||||||
|
pub mod day02;
|
||||||
|
// pub mod day03;
|
||||||
|
// pub mod day04;
|
||||||
|
// pub mod day05;
|
||||||
|
// pub mod day06;
|
||||||
|
// pub mod day07;
|
||||||
|
// pub mod day08;
|
||||||
|
// pub mod day09;
|
||||||
|
// pub mod day10;
|
||||||
|
// pub mod day11;
|
||||||
|
// pub mod day12;
|
||||||
|
// pub mod day13;
|
||||||
|
// pub mod day14;
|
||||||
|
// pub mod day15;
|
||||||
|
// pub mod day16;
|
||||||
|
// pub mod day17;
|
||||||
|
// pub mod day18;
|
||||||
|
// pub mod day19;
|
||||||
|
// pub mod day20;
|
||||||
|
// pub mod day21;
|
||||||
|
// pub mod day22;
|
||||||
|
// pub mod day23;
|
||||||
|
// pub mod day24;
|
||||||
|
// pub mod day25;
|
||||||
pub mod helpers;
|
pub mod helpers;
|
||||||
|
|
||||||
pub const ANSI_ITALIC: &str = "\x1b[3m";
|
pub const ANSI_ITALIC: &str = "\x1b[3m";
|
||||||
|
|
Loading…
Add table
Reference in a new issue