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:
2023-11-20 15:44:14 +01:00
parent 0000029068
commit 0000030025
9 changed files with 85 additions and 38 deletions

14
utils/download/Cargo.toml Normal file
View File

@@ -0,0 +1,14 @@
[package]
name = "download"
description.workspace = true
readme.workspace = true
version.workspace = true
edition.workspace = true
license.workspace = true
authors.workspace = true
repository.workspace = true
[dependencies]
reqwest = { version = "0.11.22", features = ["blocking"] }
dotenvy = "0.15.6"
pico-args = "0.5.0"

View File

@@ -0,0 +1,64 @@
use dotenvy::dotenv;
use reqwest::blocking::Client;
use reqwest::header;
use std::{env, fs::OpenOptions, io::Write, process};
pub fn parse_args() -> Result<u8, pico_args::Error> {
let mut args = pico_args::Arguments::from_env();
args.free_from_str()
}
fn main() {
let day: u8 = match 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);
}
}
}

14
utils/scaffold/Cargo.toml Normal file
View File

@@ -0,0 +1,14 @@
[package]
name = "scaffold"
description.workspace = true
readme.workspace = true
version.workspace = true
edition.workspace = true
license.workspace = true
authors.workspace = true
repository.workspace = true
[dependencies]
reqwest = { version = "0.11.22", features = ["blocking"] }
dotenvy = "0.15.6"
pico-args = "0.5.0"

109
utils/scaffold/src/main.rs Normal file
View File

@@ -0,0 +1,109 @@
/*
* 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);
}
}
"#;
pub fn parse_args() -> Result<u8, pico_args::Error> {
let mut args = pico_args::Arguments::from_env();
args.free_from_str()
}
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 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
);
}