feat!: prune main and download_all and remove tokio dep

This commit is contained in:
2023-11-18 19:31:44 +01:00
parent 000002605d
commit 00000270a3
7 changed files with 22 additions and 326 deletions

View File

@@ -1,9 +1,9 @@
use dotenvy::dotenv;
use reqwest::{header, Client};
use reqwest::blocking::Client;
use reqwest::header;
use std::{env, fs::OpenOptions, io::Write, process};
#[tokio::main]
async fn main() {
fn main() {
let day: u8 = match aoc::parse_args() {
Ok(day) => day,
Err(_) => {
@@ -30,10 +30,8 @@ async fn main() {
let res = client
.get(format!("https://adventofcode.com/{year}/day/{day}/input"))
.send()
.await
.unwrap()
.text()
.await
.unwrap();
let input_path = format!("src/inputs/{day_padded}.txt");

View File

@@ -1,57 +0,0 @@
use dotenvy::dotenv;
use itertools::Itertools;
use reqwest::{header, Client};
use std::{env, fs::OpenOptions, io::Write, process};
#[tokio::main]
async fn main() {
dotenv().ok();
let token = env::var("TOKEN").expect("$TOKEN is not set");
let year = env::var("YEAR")
.expect("$YEAR is not set")
.parse::<u32>()
.expect("$YEAR must be a number");
let mut headers = header::HeaderMap::new();
let mut session_header = header::HeaderValue::from_str(format!("session={token}").as_str())
.expect("Error building cookie header");
session_header.set_sensitive(true);
headers.insert(header::COOKIE, session_header);
let client = Client::builder().default_headers(headers).build().unwrap();
let responses = (1..=25)
.map(|d| {
let endpoint = format!("https://adventofcode.com/{year}/day/{d}/input");
println!("{endpoint}");
client.get(endpoint).send()
})
.collect_vec()
.into_iter()
.map(|x| async { x.await.unwrap().text().await.unwrap() })
.collect_vec();
for (day, res) in (1..=25).zip(responses) {
let input_path = format!("src/inputs/{day:02}.txt");
let mut file = match OpenOptions::new()
.write(true)
.create(true)
.open(&input_path)
{
Ok(file) => file,
Err(e) => {
eprintln!("Failed to create module file: {e}");
process::exit(1);
}
};
match file.write_all(res.await.as_bytes()) {
Ok(_) => {
println!("Downloaded input file \"{}\"", &input_path);
}
Err(e) => {
eprintln!("Failed to write module contents: {e}");
process::exit(1);
}
}
}
}

View File

@@ -8,7 +8,7 @@ use std::{
process,
};
const MODULE_TEMPLATE: &str = r###"pub fn part_one(input: &str) -> Option<u32> {
const MODULE_TEMPLATE: &str = r#"pub fn part_one(input: &str) -> Option<u32> {
None
}
pub fn part_two(input: &str) -> Option<u32> {
@@ -33,7 +33,7 @@ mod tests {
assert_eq!(part_two(&input), None);
}
}
"###;
"#;
fn safe_create_file(path: &str) -> Result<File, std::io::Error> {
OpenOptions::new().write(true).create_new(true).open(path)

View File

@@ -48,80 +48,8 @@ pub fn read_file(folder: &str, day: u8) -> String {
f.expect("could not open input file")
}
fn parse_time(val: &str, postfix: &str) -> f64 {
val.split(postfix).next().unwrap().parse().unwrap()
}
pub fn parse_args() -> Result<u8, pico_args::Error> {
let mut args = pico_args::Arguments::from_env();
args.free_from_str()
}
pub fn parse_exec_time(output: &str) -> f64 {
output.lines().fold(0_f64, |acc, l| {
if !l.contains("elapsed:") {
acc
} else {
let timing = l.split("(elapsed: ").last().unwrap();
// use `contains` istd. of `ends_with`: string may contain ANSI escape sequences.
// for possible time formats, see: https://github.com/rust-lang/rust/blob/1.64.0/library/core/src/time.rs#L1176-L1200
if timing.contains("ns)") {
acc // range below rounding precision.
} else if timing.contains("µs)") {
acc + parse_time(timing, "µs") / 1000_f64
} else if timing.contains("ms)") {
acc + parse_time(timing, "ms")
} else if timing.contains("s)") {
acc + parse_time(timing, "s") * 1000_f64
} else {
acc
}
}
})
}
/// copied from: https://github.com/rust-lang/rust/blob/1.64.0/library/std/src/macros.rs#L328-L333
#[cfg(test)]
macro_rules! assert_approx_eq {
($a:expr, $b:expr) => {{
let (a, b) = (&$a, &$b);
assert!(
(*a - *b).abs() < 1.0e-6,
"{} is not approximately equal to {}",
*a,
*b
);
}};
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_exec_time() {
assert_approx_eq!(
parse_exec_time(&format!(
"🎄 Part 1 🎄\n0 (elapsed: 74.13ns){ANSI_RESET}\n🎄 Part 2 🎄\n0 (elapsed: 50.00ns){ANSI_RESET}"
)),
0_f64
);
assert_approx_eq!(
parse_exec_time("🎄 Part 1 🎄\n0 (elapsed: 755µs)\n🎄 Part 2 🎄\n0 (elapsed: 700µs)"),
1.455_f64
);
assert_approx_eq!(
parse_exec_time("🎄 Part 1 🎄\n0 (elapsed: 70µs)\n🎄 Part 2 🎄\n0 (elapsed: 1.45ms)"),
1.52_f64
);
assert_approx_eq!(
parse_exec_time(
"🎄 Part 1 🎄\n0 (elapsed: 10.3s)\n🎄 Part 2 🎄\n0 (elapsed: 100.50ms)"
),
10400.50_f64
);
}
}

View File

@@ -1,43 +0,0 @@
/*
* This file contains template code.
* There is no need to edit this file unless you want to change template functionality.
*/
use aoc::{ANSI_BOLD, ANSI_ITALIC, ANSI_RESET};
use std::process::Command;
fn main() {
let total: f64 = (1..=25)
.map(|day| {
let day = format!("{day:02}");
let cmd = Command::new("cargo")
.args(["run", "--release", "--bin", &day])
.output()
.unwrap();
println!("----------");
println!("{ANSI_BOLD}| Day {day} |{ANSI_RESET}");
println!("----------");
let output = String::from_utf8(cmd.stdout).unwrap();
let is_empty = output.is_empty();
println!(
"{}",
if is_empty {
"Not solved."
} else {
output.trim()
}
);
if is_empty {
0_f64
} else {
aoc::parse_exec_time(&output)
}
})
.sum();
println!("{ANSI_BOLD}Total:{ANSI_RESET} {ANSI_ITALIC}{total:.2}ms{ANSI_RESET}");
}