feat!: decouple download and scaffold from main package into workspace
Added workspace structure to Cargo.toml. This way we don't need to build all dependencies for helper binaries. Also changed .cargo/config accordingly.
This commit is contained in:
		@@ -1,59 +0,0 @@
 | 
			
		||||
use dotenvy::dotenv;
 | 
			
		||||
use reqwest::blocking::Client;
 | 
			
		||||
use reqwest::header;
 | 
			
		||||
use std::{env, fs::OpenOptions, io::Write, process};
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    let day: u8 = match aoc::parse_args() {
 | 
			
		||||
        Ok(day) => day,
 | 
			
		||||
        Err(_) => {
 | 
			
		||||
            eprintln!("Need to specify a day (as integer). example: `cargo download 7`");
 | 
			
		||||
            process::exit(1);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    dotenv().ok();
 | 
			
		||||
 | 
			
		||||
    let day_padded = format!("{day:02}");
 | 
			
		||||
    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 res = client
 | 
			
		||||
        .get(format!("https://adventofcode.com/{year}/day/{day}/input"))
 | 
			
		||||
        .send()
 | 
			
		||||
        .unwrap()
 | 
			
		||||
        .text()
 | 
			
		||||
        .unwrap();
 | 
			
		||||
 | 
			
		||||
    let input_path = format!("src/inputs/{day_padded}.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.as_bytes()) {
 | 
			
		||||
        Ok(_) => {
 | 
			
		||||
            println!("Downloaded input file \"{}\"", &input_path);
 | 
			
		||||
        }
 | 
			
		||||
        Err(e) => {
 | 
			
		||||
            eprintln!("Failed to write module contents: {e}");
 | 
			
		||||
            process::exit(1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,104 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * This file contains template code.
 | 
			
		||||
 * There is no need to edit this file unless you want to change template functionality.
 | 
			
		||||
 */
 | 
			
		||||
use std::{
 | 
			
		||||
    fs::{File, OpenOptions},
 | 
			
		||||
    io::Write,
 | 
			
		||||
    process,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const MODULE_TEMPLATE: &str = r#"pub fn part_one(input: &str) -> Option<u32> {
 | 
			
		||||
    None
 | 
			
		||||
}
 | 
			
		||||
pub fn part_two(input: &str) -> Option<u32> {
 | 
			
		||||
    None
 | 
			
		||||
}
 | 
			
		||||
fn main() {
 | 
			
		||||
    let input = &aoc::read_file("inputs", DAY);
 | 
			
		||||
    aoc::solve!(1, part_one, input);
 | 
			
		||||
    aoc::solve!(2, part_two, input);
 | 
			
		||||
}
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod tests {
 | 
			
		||||
    use super::*;
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_part_one() {
 | 
			
		||||
        let input = aoc::read_file("examples", DAY);
 | 
			
		||||
        assert_eq!(part_one(&input), None);
 | 
			
		||||
    }
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn test_part_two() {
 | 
			
		||||
        let input = aoc::read_file("examples", DAY);
 | 
			
		||||
        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)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn create_file(path: &str) -> Result<File, std::io::Error> {
 | 
			
		||||
    OpenOptions::new().write(true).create(true).open(path)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    let day = match aoc::parse_args() {
 | 
			
		||||
        Ok(day) => day,
 | 
			
		||||
        Err(_) => {
 | 
			
		||||
            eprintln!("Need to specify a day (as integer). example: `cargo scaffold 7`");
 | 
			
		||||
            process::exit(1);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    let day_padded = format!("{day:02}");
 | 
			
		||||
 | 
			
		||||
    let input_path = format!("src/inputs/{day_padded}.txt");
 | 
			
		||||
    let example_path = format!("src/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}");
 | 
			
		||||
            process::exit(1);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    match file.write_all(MODULE_TEMPLATE.replace("DAY", &day.to_string()).as_bytes()) {
 | 
			
		||||
        Ok(_) => {
 | 
			
		||||
            println!("Created module file \"{}\"", &module_path);
 | 
			
		||||
        }
 | 
			
		||||
        Err(e) => {
 | 
			
		||||
            eprintln!("Failed to write module contents: {e}");
 | 
			
		||||
            process::exit(1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    match create_file(&input_path) {
 | 
			
		||||
        Ok(_) => {
 | 
			
		||||
            println!("Created empty input file \"{}\"", &input_path);
 | 
			
		||||
        }
 | 
			
		||||
        Err(e) => {
 | 
			
		||||
            eprintln!("Failed to create input file: {e}");
 | 
			
		||||
            process::exit(1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    match create_file(&example_path) {
 | 
			
		||||
        Ok(_) => {
 | 
			
		||||
            println!("Created empty example file \"{}\"", &example_path);
 | 
			
		||||
        }
 | 
			
		||||
        Err(e) => {
 | 
			
		||||
            eprintln!("Failed to create example file: {e}");
 | 
			
		||||
            process::exit(1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    println!("---");
 | 
			
		||||
    println!(
 | 
			
		||||
        "🎄 Type `cargo solve {}` to run your solution.",
 | 
			
		||||
        &day_padded
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
@@ -47,8 +47,3 @@ pub fn read_file(folder: &str, day: u8) -> String {
 | 
			
		||||
    let f = fs::read_to_string(filepath);
 | 
			
		||||
    f.expect("could not open input file").trim().to_string()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn parse_args() -> Result<u8, pico_args::Error> {
 | 
			
		||||
    let mut args = pico_args::Arguments::from_env();
 | 
			
		||||
    args.free_from_str()
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user