This commit is contained in:
RingOfStorms (Joshua Bell) 2023-12-01 20:09:57 -06:00
commit b2f78d33e7
12 changed files with 3245 additions and 0 deletions

61
src/utils/aoc.rs Normal file
View file

@ -0,0 +1,61 @@
use crate::prelude::*;
use reqwest::{
header::{self, COOKIE},
Client,
};
use reqwest_middleware::{ClientBuilder as MiddlewareClientBuilder, ClientWithMiddleware};
use reqwest_retry::{policies::ExponentialBackoff, RetryTransientMiddleware};
use std::fs::{self, File};
use std::io::{Read, Write};
use std::path::PathBuf;
static AOC_PUZZLE_INPUT_CACHE: &str = "aoc_puzzle_cache";
pub async fn get_puzzle_input(day: i8) -> Result<String> {
let file_name = format!("day_{}", day);
let cache_path = PathBuf::from(AOC_PUZZLE_INPUT_CACHE).join(file_name);
if cache_path.exists() {
// Read from the cache file
let mut cache_file = File::open(cache_path)?;
let mut contents = String::new();
cache_file.read_to_string(&mut contents)?;
Ok(contents)
} else {
// Fetch the content from the URL
let response = aoc_client()
.await?
.get(format!("https://adventofcode.com/2023/day/{}/input", day))
.send()
.await?
.text()
.await?;
// Cache the content to a file Ensure the cache directory exists
fs::create_dir_all(AOC_PUZZLE_INPUT_CACHE)?;
let mut cache_file = File::create(cache_path)?;
cache_file.write_all(response.as_bytes())?;
Ok(response)
}
}
pub async fn aoc_client() -> Result<ClientWithMiddleware> {
let session = &get_config().aoc_session;
let mut session_cookie = header::HeaderValue::from_str(&format!("session={}", session))
.expect("failed to create header with api_key.");
session_cookie.set_sensitive(true);
let mut headers = header::HeaderMap::new();
headers.insert(COOKIE, session_cookie);
let client = Client::builder()
.default_headers(headers)
.gzip(true)
.brotli(true)
.deflate(true)
.https_only(false)
.build()?;
let client = MiddlewareClientBuilder::new(client)
.with(RetryTransientMiddleware::new_with_policy(
ExponentialBackoff::builder().build_with_max_retries(2),
))
.build();
Ok(client)
}

4
src/utils/common.rs Normal file
View file

@ -0,0 +1,4 @@
pub type SResult<T, R> = std::result::Result<T, R>;
pub type SError = dyn std::error::Error;
pub type BoxE = Box<SError>;
pub type Result<T> = SResult<T, BoxE>;

21
src/utils/config.rs Normal file
View file

@ -0,0 +1,21 @@
use std::{
env::var,
sync::OnceLock,
};
static CONFIG: OnceLock<Config> = OnceLock::new();
pub struct Config {
pub aoc_session: String,
}
impl Config { }
fn get_var(var_name: &str) -> String {
var(var_name).unwrap_or("".to_owned())
}
pub fn get_config() -> &'static Config {
let config = CONFIG.get_or_init(|| Config { aoc_session: get_var("AOC_SESSION") });
config
}

3
src/utils/mod.rs Normal file
View file

@ -0,0 +1,3 @@
pub mod common;
pub mod config;
pub mod aoc;