refactor: fix most pedantic clippy warnings
closes #29 Co-authored-by: Andy Pymont <andypymont@gmail.com>
This commit is contained in:
parent
f46d1e209c
commit
d7af3dca9e
10 changed files with 107 additions and 114 deletions
41
src/main.rs
41
src/main.rs
|
@ -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,
|
||||
},
|
||||
|
@ -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 => {
|
||||
|
@ -64,7 +61,7 @@ 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)
|
||||
|
@ -72,22 +69,22 @@ mod 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),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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> {
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ 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| {
|
||||
|
@ -13,7 +13,7 @@ pub fn all_handler(is_release: bool, is_timed: bool) {
|
|||
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();
|
||||
|
@ -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.");
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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() {
|
||||
|
@ -121,7 +119,7 @@ mod child_commands {
|
|||
|
||||
for line in stdout.lines() {
|
||||
let line = line.unwrap();
|
||||
println!("{}", line);
|
||||
println!("{line}");
|
||||
output.push(line);
|
||||
}
|
||||
|
||||
|
@ -146,12 +144,9 @@ mod child_commands {
|
|||
return None;
|
||||
}
|
||||
|
||||
let (timing_str, nanos) = match parse_time(l) {
|
||||
Some(v) => v,
|
||||
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()?;
|
||||
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::process::{Command, Stdio};
|
||||
|
||||
pub fn solve_handler(day: u8, release: bool, time: bool, submit_part: Option<u8>) {
|
||||
let day_padded = format!("{:02}", day);
|
||||
pub fn handle(day: u8, release: bool, time: bool, submit_part: Option<u8>) {
|
||||
let day_padded = format!("{day:02}");
|
||||
|
||||
let mut cmd_args = vec!["run".to_string(), "--bin".to_string(), day_padded];
|
||||
|
||||
|
@ -13,7 +13,7 @@ pub fn solve_handler(day: u8, release: bool, time: bool, submit_part: Option<u8>
|
|||
|
||||
if let Some(submit_part) = submit_part {
|
||||
cmd_args.push("--submit".to_string());
|
||||
cmd_args.push(submit_part.to_string())
|
||||
cmd_args.push(submit_part.to_string());
|
||||
}
|
||||
|
||||
if time {
|
||||
|
|
|
@ -10,12 +10,12 @@ pub const ANSI_BOLD: &str = "\x1b[1m";
|
|||
pub const ANSI_RESET: &str = "\x1b[0m";
|
||||
|
||||
/// Helper function that reads a text file to a string.
|
||||
pub fn read_file(folder: &str, day: u8) -> String {
|
||||
#[must_use] pub fn read_file(folder: &str, day: u8) -> String {
|
||||
let cwd = env::current_dir().unwrap();
|
||||
let filepath = cwd
|
||||
.join("data")
|
||||
.join(folder)
|
||||
.join(format!("{:02}.txt", day));
|
||||
.join(format!("{day:02}.txt"));
|
||||
let f = fs::read_to_string(filepath);
|
||||
f.expect("could not open input file")
|
||||
}
|
||||
|
|
|
@ -29,9 +29,9 @@ pub struct TablePosition {
|
|||
pos_end: usize,
|
||||
}
|
||||
|
||||
pub fn get_path_for_bin(day: usize) -> String {
|
||||
let day_padded = format!("{:02}", day);
|
||||
format!("./src/bin/{}.rs", day_padded)
|
||||
#[must_use] pub fn get_path_for_bin(day: usize) -> String {
|
||||
let day_padded = format!("{day:02}");
|
||||
format!("./src/bin/{day_padded}.rs")
|
||||
}
|
||||
|
||||
fn locate_table(readme: &str) -> Result<TablePosition, Error> {
|
||||
|
@ -62,12 +62,12 @@ fn construct_table(prefix: &str, timings: Vec<Timings>, total_millis: f64) -> St
|
|||
let mut lines: Vec<String> = vec![
|
||||
MARKER.into(),
|
||||
header,
|
||||
"".into(),
|
||||
String::new(),
|
||||
"| Day | Part 1 | Part 2 |".into(),
|
||||
"| :---: | :---: | :---: |".into(),
|
||||
];
|
||||
|
||||
timings.into_iter().for_each(|timing| {
|
||||
for timing in timings {
|
||||
let path = get_path_for_bin(timing.day);
|
||||
lines.push(format!(
|
||||
"| [Day {}]({}) | `{}` | `{}` |",
|
||||
|
@ -76,10 +76,10 @@ fn construct_table(prefix: &str, timings: Vec<Timings>, total_millis: f64) -> St
|
|||
timing.part_1.unwrap_or_else(|| "-".into()),
|
||||
timing.part_2.unwrap_or_else(|| "-".into())
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
lines.push("".into());
|
||||
lines.push(format!("**Total: {:.2}ms**", total_millis));
|
||||
lines.push(String::new());
|
||||
lines.push(format!("**Total: {total_millis:.2}ms**"));
|
||||
lines.push(MARKER.into());
|
||||
|
||||
lines.join("\n")
|
||||
|
|
|
@ -9,7 +9,7 @@ use std::{cmp, env, process};
|
|||
use super::ANSI_BOLD;
|
||||
|
||||
pub fn run_part<I: Clone, T: Display>(func: impl Fn(I) -> Option<T>, input: I, day: u8, part: u8) {
|
||||
let part_str = format!("Part {}", part);
|
||||
let part_str = format!("Part {part}");
|
||||
|
||||
let (result, duration, samples) =
|
||||
run_timed(func, input, |result| print_result(result, &part_str, ""));
|
||||
|
@ -35,9 +35,10 @@ fn run_timed<I: Clone, T>(
|
|||
|
||||
hook(&result);
|
||||
|
||||
let run = match std::env::args().any(|x| x == "--time") {
|
||||
true => bench(func, input, &base_time),
|
||||
false => (base_time, 1),
|
||||
let run = if std::env::args().any(|x| x == "--time") {
|
||||
bench(func, input, &base_time)
|
||||
} else {
|
||||
(base_time, 1)
|
||||
};
|
||||
|
||||
(result, run.0, run.1)
|
||||
|
@ -46,7 +47,7 @@ fn run_timed<I: Clone, T>(
|
|||
fn bench<I: Clone, T>(func: impl Fn(I) -> T, input: I, base_time: &Duration) -> (Duration, u128) {
|
||||
let mut stdout = stdout();
|
||||
|
||||
print!(" > {}benching{}", ANSI_ITALIC, ANSI_RESET);
|
||||
print!(" > {ANSI_ITALIC}benching{ANSI_RESET}");
|
||||
let _ = stdout.flush();
|
||||
|
||||
let bench_iterations = cmp::min(
|
||||
|
@ -68,20 +69,25 @@ fn bench<I: Clone, T>(func: impl Fn(I) -> T, input: I, base_time: &Duration) ->
|
|||
}
|
||||
|
||||
(
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
Duration::from_nanos(average_duration(&timers) as u64),
|
||||
bench_iterations,
|
||||
)
|
||||
}
|
||||
|
||||
fn average_duration(numbers: &[Duration]) -> u128 {
|
||||
numbers.iter().map(|d| d.as_nanos()).sum::<u128>() / numbers.len() as u128
|
||||
numbers
|
||||
.iter()
|
||||
.map(std::time::Duration::as_nanos)
|
||||
.sum::<u128>()
|
||||
/ numbers.len() as u128
|
||||
}
|
||||
|
||||
fn format_duration(duration: &Duration, samples: u128) -> String {
|
||||
if samples == 1 {
|
||||
format!(" ({:.1?})", duration)
|
||||
format!(" ({duration:.1?})")
|
||||
} else {
|
||||
format!(" ({:.1?} @ {} samples)", duration, samples)
|
||||
format!(" ({duration:.1?} @ {samples} samples)")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,33 +97,30 @@ fn print_result<T: Display>(result: &Option<T>, part: &str, duration_str: &str)
|
|||
match result {
|
||||
Some(result) => {
|
||||
if result.to_string().contains('\n') {
|
||||
let str = format!("{}: ▼ {}", part, duration_str);
|
||||
let str = format!("{part}: ▼ {duration_str}");
|
||||
if is_intermediate_result {
|
||||
print!("{}", str);
|
||||
print!("{str}");
|
||||
} else {
|
||||
print!("\r");
|
||||
println!("{}", str);
|
||||
println!("{}", result);
|
||||
println!("{str}");
|
||||
println!("{result}");
|
||||
}
|
||||
} else {
|
||||
let str = format!(
|
||||
"{}: {}{}{}{}",
|
||||
part, ANSI_BOLD, result, ANSI_RESET, duration_str
|
||||
);
|
||||
let str = format!("{part}: {ANSI_BOLD}{result}{ANSI_RESET}{duration_str}");
|
||||
if is_intermediate_result {
|
||||
print!("{}", str);
|
||||
print!("{str}");
|
||||
} else {
|
||||
print!("\r");
|
||||
println!("{}", str);
|
||||
println!("{str}");
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {
|
||||
if is_intermediate_result {
|
||||
print!("{}: ✖", part);
|
||||
print!("{part}: ✖");
|
||||
} else {
|
||||
print!("\r");
|
||||
println!("{}: ✖ ", part);
|
||||
println!("{part}: ✖ ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -130,7 +133,7 @@ fn submit_result<T: Display>(
|
|||
result: T,
|
||||
day: u8,
|
||||
part: u8,
|
||||
) -> Option<Result<Output, aoc_cli::AocCliError>> {
|
||||
) -> Option<Result<Output, aoc_cli::AocCommandError>> {
|
||||
let args: Vec<String> = env::args().collect();
|
||||
|
||||
if !args.contains(&"--submit".into()) {
|
||||
|
@ -143,12 +146,10 @@ fn submit_result<T: Display>(
|
|||
}
|
||||
|
||||
let part_index = args.iter().position(|x| x == "--submit").unwrap() + 1;
|
||||
let part_submit = match args[part_index].parse::<u8>() {
|
||||
Ok(x) => x,
|
||||
Err(_) => {
|
||||
|
||||
let Ok(part_submit) = args[part_index].parse::<u8>() else {
|
||||
eprintln!("Unexpected command-line input. Format: cargo solve 1 --submit 1");
|
||||
process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
if part_submit != part {
|
||||
|
|
Loading…
Add table
Reference in a new issue