Skip to content

Commit

Permalink
refactor: fix most pedantic clippy warnings
Browse files Browse the repository at this point in the history
closes #29

Co-authored-by: Andy Pymont <[email protected]>
  • Loading branch information
fspoettel and andypymont committed Oct 31, 2023
1 parent f46d1e2 commit d7af3dc
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 114 deletions.
41 changes: 19 additions & 22 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
use advent_of_code::template::commands::{
all::all_handler, download::download_handler, read::read_handler, scaffold::scaffold_handler,
solve::solve_handler,
};
use args::{parse_args, AppArgs};
use advent_of_code::template::commands::{all, download, read, scaffold, solve};
use args::{parse, AppArguments};

mod args {
use std::process;

pub enum AppArgs {
pub enum AppArguments {
Download {
day: u8,
},
Expand All @@ -29,31 +26,31 @@ mod args {
},
}

pub fn parse_args() -> Result<AppArgs, Box<dyn std::error::Error>> {
pub fn parse() -> Result<AppArguments, Box<dyn std::error::Error>> {
let mut args = pico_args::Arguments::from_env();

let app_args = match args.subcommand()?.as_deref() {
Some("all") => AppArgs::All {
Some("all") => AppArguments::All {
release: args.contains("--release"),
time: args.contains("--time"),
},
Some("download") => AppArgs::Download {
Some("download") => AppArguments::Download {
day: args.free_from_str()?,
},
Some("read") => AppArgs::Read {
Some("read") => AppArguments::Read {
day: args.free_from_str()?,
},
Some("scaffold") => AppArgs::Scaffold {
Some("scaffold") => AppArguments::Scaffold {
day: args.free_from_str()?,
},
Some("solve") => AppArgs::Solve {
Some("solve") => AppArguments::Solve {
day: args.free_from_str()?,
release: args.contains("--release"),
submit: args.opt_value_from_str("--submit")?,
time: args.contains("--time"),
},
Some(x) => {
eprintln!("Unknown command: {}", x);
eprintln!("Unknown command: {x}");
process::exit(1);
}
None => {
Expand All @@ -64,30 +61,30 @@ mod args {

let remaining = args.finish();
if !remaining.is_empty() {
eprintln!("Warning: unknown argument(s): {:?}.", remaining);
eprintln!("Warning: unknown argument(s): {remaining:?}.");
}

Ok(app_args)
}
}

fn main() {
match parse_args() {
match parse() {
Err(err) => {
eprintln!("Error: {}", err);
eprintln!("Error: {err}");
std::process::exit(1);
}
Ok(args) => match args {
AppArgs::All { release, time } => all_handler(release, time),
AppArgs::Download { day } => download_handler(day),
AppArgs::Read { day } => read_handler(day),
AppArgs::Scaffold { day } => scaffold_handler(day),
AppArgs::Solve {
AppArguments::All { release, time } => all::handle(release, time),
AppArguments::Download { day } => download::handle(day),
AppArguments::Read { day } => read::handle(day),
AppArguments::Scaffold { day } => scaffold::handle(day),
AppArguments::Solve {
day,
release,
time,
submit,
} => solve_handler(day, release, time, submit),
} => solve::handle(day, release, time, submit),
},
};
}
36 changes: 18 additions & 18 deletions src/template/aoc_cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,35 @@ use std::{
};

#[derive(Debug)]
pub enum AocCliError {
pub enum AocCommandError {
CommandNotFound,
CommandNotCallable,
BadExitStatus(Output),
IoError,
}

impl Display for AocCliError {
impl Display for AocCommandError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
AocCliError::CommandNotFound => write!(f, "aoc-cli is not present in environment."),
AocCliError::CommandNotCallable => write!(f, "aoc-cli could not be called."),
AocCliError::BadExitStatus(_) => {
AocCommandError::CommandNotFound => write!(f, "aoc-cli is not present in environment."),
AocCommandError::CommandNotCallable => write!(f, "aoc-cli could not be called."),
AocCommandError::BadExitStatus(_) => {
write!(f, "aoc-cli exited with a non-zero status.")
}
AocCliError::IoError => write!(f, "could not write output files to file system."),
AocCommandError::IoError => write!(f, "could not write output files to file system."),
}
}
}

pub fn check() -> Result<(), AocCliError> {
pub fn check() -> Result<(), AocCommandError> {
Command::new("aoc")
.arg("-V")
.output()
.map_err(|_| AocCliError::CommandNotFound)?;
.map_err(|_| AocCommandError::CommandNotFound)?;
Ok(())
}

pub fn read(day: u8) -> Result<Output, AocCliError> {
pub fn read(day: u8) -> Result<Output, AocCommandError> {
let puzzle_path = get_puzzle_path(day);

let args = build_args(
Expand All @@ -49,7 +49,7 @@ pub fn read(day: u8) -> Result<Output, AocCliError> {
call_aoc_cli(&args)
}

pub fn download(day: u8) -> Result<Output, AocCliError> {
pub fn download(day: u8) -> Result<Output, AocCommandError> {
let input_path = get_input_path(day);
let puzzle_path = get_puzzle_path(day);

Expand All @@ -72,7 +72,7 @@ pub fn download(day: u8) -> Result<Output, AocCliError> {
Ok(output)
}

pub fn submit(day: u8, part: u8, result: &str) -> Result<Output, AocCliError> {
pub fn submit(day: u8, part: u8, result: &str) -> Result<Output, AocCommandError> {
// workaround: the argument order is inverted for submit.
let mut args = build_args("submit", &[], day);
args.push(part.to_string());
Expand All @@ -81,13 +81,13 @@ pub fn submit(day: u8, part: u8, result: &str) -> Result<Output, AocCliError> {
}

fn get_input_path(day: u8) -> String {
let day_padded = format!("{:02}", day);
format!("data/inputs/{}.txt", day_padded)
let day_padded = format!("{day:02}");
format!("data/inputs/{day_padded}.txt")
}

fn get_puzzle_path(day: u8) -> String {
let day_padded = format!("{:02}", day);
format!("data/puzzles/{}.md", day_padded)
let day_padded = format!("{day:02}");
format!("data/puzzles/{day_padded}.md")
}

fn get_year() -> Option<u16> {
Expand All @@ -110,18 +110,18 @@ fn build_args(command: &str, args: &[String], day: u8) -> Vec<String> {
cmd_args
}

fn call_aoc_cli(args: &[String]) -> Result<Output, AocCliError> {
fn call_aoc_cli(args: &[String]) -> Result<Output, AocCommandError> {
// println!("Calling >aoc with: {}", args.join(" "));
let output = Command::new("aoc")
.args(args)
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.output()
.map_err(|_| AocCliError::CommandNotCallable)?;
.map_err(|_| AocCommandError::CommandNotCallable)?;

if output.status.success() {
Ok(output)
} else {
Err(AocCliError::BadExitStatus(output))
Err(AocCommandError::BadExitStatus(output))
}
}
35 changes: 15 additions & 20 deletions src/template/commands/all.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ use crate::template::{
ANSI_BOLD, ANSI_ITALIC, ANSI_RESET,
};

pub fn all_handler(is_release: bool, is_timed: bool) {
pub fn handle(is_release: bool, is_timed: bool) {
let mut timings: Vec<Timings> = vec![];

(1..=25).for_each(|day| {
if day > 1 {
println!();
}

println!("{}Day {}{}", ANSI_BOLD, day, ANSI_RESET);
println!("{ANSI_BOLD}Day {day}{ANSI_RESET}");
println!("------");

let output = child_commands::run_solution(day, is_timed, is_release).unwrap();
Expand All @@ -27,16 +27,13 @@ pub fn all_handler(is_release: bool, is_timed: bool) {
});

if is_timed {
let total_millis = timings.iter().map(|x| x.total_nanos).sum::<f64>() / 1000000_f64;
let total_millis = timings.iter().map(|x| x.total_nanos).sum::<f64>() / 1_000_000_f64;

println!(
"\n{}Total:{} {}{:.2}ms{}",
ANSI_BOLD, ANSI_RESET, ANSI_ITALIC, total_millis, ANSI_RESET
);
println!("\n{ANSI_BOLD}Total:{ANSI_RESET} {ANSI_ITALIC}{total_millis:.2}ms{ANSI_RESET}");

if is_release {
match readme_benchmarks::update(timings, total_millis) {
Ok(_) => println!("Successfully updated README with benchmarks."),
Ok(()) => println!("Successfully updated README with benchmarks."),
Err(_) => {
eprintln!("Failed to update readme with benchmarks.");
}
Expand All @@ -58,9 +55,10 @@ impl From<std::io::Error> for Error {
}
}

#[must_use]
pub fn get_path_for_bin(day: usize) -> String {
let day_padded = format!("{:02}", day);
format!("./src/bin/{}.rs", day_padded)
let day_padded = format!("{day:02}");
format!("./src/bin/{day_padded}.rs")
}

/// All solutions live in isolated binaries.
Expand All @@ -80,7 +78,7 @@ mod child_commands {
is_timed: bool,
is_release: bool,
) -> Result<Vec<String>, Error> {
let day_padded = format!("{:02}", day);
let day_padded = format!("{day:02}");

// skip command invocation for days that have not been scaffolded yet.
if !Path::new(&get_path_for_bin(day)).exists() {
Expand Down Expand Up @@ -121,7 +119,7 @@ mod child_commands {

for line in stdout.lines() {
let line = line.unwrap();
println!("{}", line);
println!("{line}");
output.push(line);
}

Expand All @@ -146,12 +144,9 @@ mod child_commands {
return None;
}

let (timing_str, nanos) = match parse_time(l) {
Some(v) => v,
None => {
eprintln!("Could not parse timings from line: {l}");
return None;
}
let Some((timing_str, nanos)) = parse_time(l) else {
eprintln!("Could not parse timings from line: {l}");
return None;
};

let part = l.split(':').next()?;
Expand Down Expand Up @@ -188,8 +183,8 @@ mod child_commands {
let parsed_timing = match str_timing {
s if s.contains("ns") => s.split("ns").next()?.parse::<f64>().ok(),
s if s.contains("µs") => parse_to_float(s, "µs").map(|x| x * 1000_f64),
s if s.contains("ms") => parse_to_float(s, "ms").map(|x| x * 1000000_f64),
s => parse_to_float(s, "s").map(|x| x * 1000000000_f64),
s if s.contains("ms") => parse_to_float(s, "ms").map(|x| x * 1_000_000_f64),
s => parse_to_float(s, "s").map(|x| x * 1_000_000_000_f64),
}?;

Some((str_timing, parsed_timing))
Expand Down
4 changes: 2 additions & 2 deletions src/template/commands/download.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
use crate::template::aoc_cli;
use std::process;

pub fn download_handler(day: u8) {
pub fn handle(day: u8) {
if aoc_cli::check().is_err() {
eprintln!("command \"aoc\" not found or not callable. Try running \"cargo install aoc-cli\" to install it.");
process::exit(1);
}

if let Err(e) = aoc_cli::download(day) {
eprintln!("failed to call aoc-cli: {}", e);
eprintln!("failed to call aoc-cli: {e}");
process::exit(1);
};
}
4 changes: 2 additions & 2 deletions src/template/commands/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ use std::process;

use crate::template::aoc_cli;

pub fn read_handler(day: u8) {
pub fn handle(day: u8) {
if aoc_cli::check().is_err() {
eprintln!("command \"aoc\" not found or not callable. Try running \"cargo install aoc-cli\" to install it.");
process::exit(1);
}

if let Err(e) = aoc_cli::read(day) {
eprintln!("failed to call aoc-cli: {}", e);
eprintln!("failed to call aoc-cli: {e}");
process::exit(1);
};
}
20 changes: 10 additions & 10 deletions src/template/commands/scaffold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,27 +40,27 @@ fn create_file(path: &str) -> Result<File, std::io::Error> {
OpenOptions::new().write(true).create(true).open(path)
}

pub fn scaffold_handler(day: u8) {
let day_padded = format!("{:02}", day);
pub fn handle(day: u8) {
let day_padded = format!("{day:02}");

let input_path = format!("data/inputs/{}.txt", day_padded);
let example_path = format!("data/examples/{}.txt", day_padded);
let module_path = format!("src/bin/{}.rs", day_padded);
let input_path = format!("data/inputs/{day_padded}.txt");
let example_path = format!("data/examples/{day_padded}.txt");
let module_path = format!("src/bin/{day_padded}.rs");

let mut file = match safe_create_file(&module_path) {
Ok(file) => file,
Err(e) => {
eprintln!("Failed to create module file: {}", e);
eprintln!("Failed to create module file: {e}");
process::exit(1);
}
};

match file.write_all(MODULE_TEMPLATE.replace("DAY", &day.to_string()).as_bytes()) {
Ok(_) => {
Ok(()) => {
println!("Created module file \"{}\"", &module_path);
}
Err(e) => {
eprintln!("Failed to write module contents: {}", e);
eprintln!("Failed to write module contents: {e}");
process::exit(1);
}
}
Expand All @@ -70,7 +70,7 @@ pub fn scaffold_handler(day: u8) {
println!("Created empty input file \"{}\"", &input_path);
}
Err(e) => {
eprintln!("Failed to create input file: {}", e);
eprintln!("Failed to create input file: {e}");
process::exit(1);
}
}
Expand All @@ -80,7 +80,7 @@ pub fn scaffold_handler(day: u8) {
println!("Created empty example file \"{}\"", &example_path);
}
Err(e) => {
eprintln!("Failed to create example file: {}", e);
eprintln!("Failed to create example file: {e}");
process::exit(1);
}
}
Expand Down
Loading

0 comments on commit d7af3dc

Please sign in to comment.