feat!: prune main and download_all and remove tokio dep
This commit is contained in:
		@@ -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");
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										72
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										72
									
								
								src/lib.rs
									
									
									
									
									
								
							@@ -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
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										43
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								src/main.rs
									
									
									
									
									
								
							@@ -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}");
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user