feat: some cursed proc macro stuff to improve actual solution code

This commit is contained in:
Ashhhleyyy 2022-12-01 14:51:24 +00:00
parent b60e991f6d
commit a008c64177
Signed by: ash
GPG key ID: 83B789081A0878FB
12 changed files with 781 additions and 10 deletions

2
.envrc Normal file
View file

@ -0,0 +1,2 @@
use flake
dotenv

2
.gitignore vendored
View file

@ -1 +1,3 @@
/target
.env
/.direnv

348
Cargo.lock generated
View file

@ -21,7 +21,17 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
name = "aoc-2022"
version = "0.1.0"
dependencies = [
"aoc_proc",
"color-eyre",
"ureq",
]
[[package]]
name = "aoc_proc"
version = "0.1.0"
dependencies = [
"quote",
"syn",
]
[[package]]
@ -34,11 +44,23 @@ dependencies = [
"cc",
"cfg-if",
"libc",
"miniz_oxide",
"miniz_oxide 0.5.4",
"object",
"rustc-demangle",
]
[[package]]
name = "base64"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
name = "bumpalo"
version = "3.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
[[package]]
name = "cc"
version = "1.0.77"
@ -51,6 +73,12 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chunked_transfer"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fff857943da45f546682664a79488be82e69e43c1a7a2307679ab9afb3a66d2e"
[[package]]
name = "color-eyre"
version = "0.6.2"
@ -78,6 +106,15 @@ dependencies = [
"tracing-error",
]
[[package]]
name = "crc32fast"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
dependencies = [
"cfg-if",
]
[[package]]
name = "eyre"
version = "0.6.8"
@ -88,18 +125,56 @@ dependencies = [
"once_cell",
]
[[package]]
name = "flate2"
version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841"
dependencies = [
"crc32fast",
"miniz_oxide 0.6.2",
]
[[package]]
name = "form_urlencoded"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
dependencies = [
"percent-encoding",
]
[[package]]
name = "gimli"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
[[package]]
name = "idna"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
dependencies = [
"unicode-bidi",
"unicode-normalization",
]
[[package]]
name = "indenter"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
[[package]]
name = "js-sys"
version = "0.3.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
@ -112,6 +187,15 @@ version = "0.2.137"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
[[package]]
name = "log"
version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
"cfg-if",
]
[[package]]
name = "memchr"
version = "2.5.0"
@ -127,6 +211,15 @@ dependencies = [
"adler",
]
[[package]]
name = "miniz_oxide"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
dependencies = [
"adler",
]
[[package]]
name = "object"
version = "0.29.0"
@ -148,18 +241,79 @@ version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
[[package]]
name = "percent-encoding"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
[[package]]
name = "pin-project-lite"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
[[package]]
name = "proc-macro2"
version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
dependencies = [
"proc-macro2",
]
[[package]]
name = "ring"
version = "0.16.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
dependencies = [
"cc",
"libc",
"once_cell",
"spin",
"untrusted",
"web-sys",
"winapi",
]
[[package]]
name = "rustc-demangle"
version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
[[package]]
name = "rustls"
version = "0.20.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "539a2bfe908f471bfa933876bd1eb6a19cf2176d375f82ef7f99530a40e48c2c"
dependencies = [
"log",
"ring",
"sct",
"webpki",
]
[[package]]
name = "sct"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "sharded-slab"
version = "0.1.4"
@ -169,6 +323,23 @@ dependencies = [
"lazy_static",
]
[[package]]
name = "spin"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "syn"
version = "1.0.105"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "thread_local"
version = "1.1.4"
@ -178,6 +349,21 @@ dependencies = [
"once_cell",
]
[[package]]
name = "tinyvec"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
dependencies = [
"tinyvec_macros",
]
[[package]]
name = "tinyvec_macros"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]]
name = "tracing"
version = "0.1.37"
@ -220,8 +406,168 @@ dependencies = [
"tracing-core",
]
[[package]]
name = "unicode-bidi"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
[[package]]
name = "unicode-ident"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
[[package]]
name = "unicode-normalization"
version = "0.1.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
dependencies = [
"tinyvec",
]
[[package]]
name = "untrusted"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
[[package]]
name = "ureq"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b97acb4c28a254fd7a4aeec976c46a7fa404eac4d7c134b30c75144846d7cb8f"
dependencies = [
"base64",
"chunked_transfer",
"flate2",
"log",
"once_cell",
"rustls",
"url",
"webpki",
"webpki-roots",
]
[[package]]
name = "url"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
dependencies = [
"form_urlencoded",
"idna",
"percent-encoding",
]
[[package]]
name = "valuable"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]]
name = "wasm-bindgen"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
[[package]]
name = "web-sys"
version = "0.3.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "webpki"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
dependencies = [
"ring",
"untrusted",
]
[[package]]
name = "webpki-roots"
version = "0.22.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "368bfe657969fb01238bb756d351dcade285e0f6fcbd36dcb23359a5169975be"
dependencies = [
"webpki",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

View file

@ -5,5 +5,10 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[workspace]
members = ["aoc_proc"]
[dependencies]
color-eyre = "0.6.2"
aoc_proc = { path = "aoc_proc" }
ureq = "2.5.0"

13
aoc_proc/Cargo.toml Normal file
View file

@ -0,0 +1,13 @@
[package]
name = "aoc_proc"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
proc-macro = true
[dependencies]
quote = "1.0.21"
syn = { version = "1.0.105", features = ["full"] }

150
aoc_proc/src/lib.rs Normal file
View file

@ -0,0 +1,150 @@
use proc_macro::TokenStream;
use syn::{parse_macro_input, ItemFn, LitInt, Ident, parse::Parse, Token, punctuated::Punctuated, Expr};
use quote::{quote, ToTokens};
struct Args {
day: LitInt,
parse: Ident,
test_cases: Option<Expr>,
}
impl Parse for Args {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
fn arg_err<T: ToTokens, U: ToTokens>(prev: T, current: U) -> syn::Error {
let mut err = syn::Error::new_spanned(prev, "this parameter is overriden by a later parameter of the same name");
err.combine(syn::Error::new_spanned(current, "this parameter overrides an earlier parameter of the same name"));
err
}
#[derive(Default)]
struct WipArgs {
day: Option<LitInt>,
parse: Option<Ident>,
test_cases: Option<Expr>,
}
let mut wip = WipArgs::default();
let vars = Punctuated::<Arg, Token![,]>::parse_terminated(input)?;
for var in vars {
match var {
Arg::Day(day) => {
if let Some(wip_day) = wip.day {
return Err(arg_err(wip_day, day));
}
wip.day = Some(day);
}
Arg::Parse(parse) => {
if let Some(wip_parse) = wip.parse {
return Err(arg_err(wip_parse, parse));
}
wip.parse = Some(parse);
}
Arg::TestCases(test_cases) => {
if let Some(wip_test_cases) = wip.test_cases {
return Err(arg_err(wip_test_cases, test_cases));
}
wip.test_cases = Some(test_cases);
}
}
}
let day = match wip.day {
Some(day) => day,
None => {
return Err(input.error("missing argument `day`"));
}
};
let parse = match wip.parse {
Some(parse) => parse,
None => {
return Err(input.error("missing argument `parse`"));
}
};
Ok(Self {
day,
parse,
test_cases: wip.test_cases,
})
}
}
enum Arg {
Day(LitInt),
Parse(Ident),
TestCases(Expr),
}
impl Parse for Arg {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
let lookahead = input.lookahead1();
let ident: Ident = input.parse()?;
input.parse::<Token![=]>()?;
match &*ident.to_string() {
"day" => Ok(Self::Day(input.parse()?)),
"parse" => Ok(Self::Parse(input.parse()?)),
"test_cases" => Ok(Self::TestCases(input.parse()?)),
_ => Err(lookahead.error()),
}
}
}
#[proc_macro_attribute]
pub fn aoc(attr: TokenStream, item: TokenStream) -> TokenStream {
let Args {
day,
parse,
test_cases,
} = parse_macro_input!(attr as Args);
let input = parse_macro_input!(item as ItemFn);
let fn_name = input.sig.ident.clone();
if let Some(test_cases) = test_cases {
TokenStream::from(quote! {
#input
fn main_case() -> ::color_eyre::Result<()> {
let input = ::aoc_2022::load_data(#day, #parse)?;
#fn_name(input)
}
fn test_cases() -> ::color_eyre::Result<()> {
let test_cases: &[&str] = &#test_cases;
println!("!!! WARNING: RUNNING TEST CASES ONLY !!!");
for case in test_cases {
println!("=== {case} ===", case = case);
let input_path = ::std::path::Path::new("test_cases").join(case);
let input = ::std::fs::read_to_string(input_path)?;
let parsed = #parse(&input)?;
#fn_name(parsed)?;
println!();
}
Ok(())
}
fn main() -> ::color_eyre::Result<()> {
let run_actual_data = std::env::args().any(|arg| arg == "--full-data");
if run_actual_data {
main_case()
} else {
test_cases()
}
}
})
} else {
TokenStream::from(quote! {
fn main() -> ::color_eyre::Result<()> {
#input
let input = ::aoc_2022::load_data(#day, #parse)?;
#fn_name(input)
}
})
}
}

123
flake.lock Normal file
View file

@ -0,0 +1,123 @@
{
"nodes": {
"crane": {
"inputs": {
"flake-compat": "flake-compat",
"flake-utils": "flake-utils",
"nixpkgs": [
"nixpkgs"
],
"rust-overlay": "rust-overlay"
},
"locked": {
"lastModified": 1669853699,
"narHash": "sha256-SvyPRwJeET7PCifBOvu+reQUUlyc4Ya1K37GrtZyiXY=",
"owner": "ipetkov",
"repo": "crane",
"rev": "0428181b7b8f619e71095cf2fab051bccdf10041",
"type": "github"
},
"original": {
"owner": "ipetkov",
"repo": "crane",
"type": "github"
}
},
"flake-compat": {
"flake": false,
"locked": {
"lastModified": 1650374568,
"narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=",
"owner": "edolstra",
"repo": "flake-compat",
"rev": "b4a34015c698c7793d592d66adbab377907a2be8",
"type": "github"
},
"original": {
"owner": "edolstra",
"repo": "flake-compat",
"type": "github"
}
},
"flake-utils": {
"locked": {
"lastModified": 1667395993,
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_2": {
"locked": {
"lastModified": 1667395993,
"narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1669809720,
"narHash": "sha256-RMT77f6CPOYtLLQ2esj+EJ1BPVWxf4RDidjrSvA5OhI=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "227de2b3bbec142f912c09d5e8a1b4e778aa54fb",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"crane": "crane",
"flake-utils": "flake-utils_2",
"nixpkgs": "nixpkgs"
}
},
"rust-overlay": {
"inputs": {
"flake-utils": [
"crane",
"flake-utils"
],
"nixpkgs": [
"crane",
"nixpkgs"
]
},
"locked": {
"lastModified": 1667487142,
"narHash": "sha256-bVuzLs1ZVggJAbJmEDVO9G6p8BH3HRaolK70KXvnWnU=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "cf668f737ac986c0a89e83b6b2e3c5ddbd8cf33b",
"type": "github"
},
"original": {
"owner": "oxalica",
"repo": "rust-overlay",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

79
flake.nix Normal file
View file

@ -0,0 +1,79 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
crane.url = "github:ipetkov/crane";
crane.inputs.nixpkgs.follows = "nixpkgs";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, crane, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs {
system = system;
};
inherit (pkgs) lib;
craneLib = crane.lib.${system};
src = craneLib.cleanCargoSource ./.;
buildInputs = [
pkgs.bintools
] ++ lib.optionals pkgs.stdenv.isDarwin [
# Additional darwin specific inputs can be set here
pkgs.libiconv
];
cargoArtifacts = craneLib.buildDepsOnly {
inherit src buildInputs;
};
# Build the actual crate itself, reusing the dependency
# artifacts from above.
aoc-2022 = craneLib.buildPackage {
inherit cargoArtifacts src buildInputs;
};
in
{
checks = {
# Build the crate as part of `nix flake check` for convenience
inherit aoc-2022;
# Run clippy (and deny all warnings) on the crate source,
# again, resuing the dependency artifacts from above.
#
# Note that this is done as a separate derivation so that
# we can block the CI if there are issues here, but not
# prevent downstream consumers from building our crate by itself.
aoc-2022-clippy = craneLib.cargoClippy {
inherit cargoArtifacts src buildInputs;
cargoClippyExtraArgs = "--all-targets -- --deny warnings";
};
# Check formatting
aoc-2022-fmt = craneLib.cargoFmt {
inherit src;
};
};
packages.default = aoc-2022;
apps.default = flake-utils.lib.mkApp {
drv = aoc-2022;
};
devShells.default = pkgs.mkShell {
inputsFrom = builtins.attrValues self.checks;
# Extra inputs can be added here
nativeBuildInputs = with pkgs; [
cargo
cargo-expand
rustc
rustfmt
bintools
];
};
});
}

View file

@ -1,6 +1,8 @@
use color_eyre::{eyre::eyre, Result};
use aoc_2022::prelude::*;
fn parse(s: String) -> Result<Vec<(usize, usize)>> {
type Input = Vec<(usize, usize)>;
fn parse(s: &str) -> Result<Input> {
let mut elves = vec![];
let mut current_elf = 1;
@ -19,9 +21,8 @@ fn parse(s: String) -> Result<Vec<(usize, usize)>> {
Ok(elves)
}
fn main() -> Result<()> {
let mut input = aoc_2022::load_data(1, parse)?;
#[aoc(day = 1, parse = parse, test_cases = ["day_1.txt"])]
fn day_1(mut input: Input) -> Result<()> {
input.sort_by_key(|(_, sum)| *sum);
let max = input[input.len() - 1].1;

View file

@ -1,6 +1,42 @@
use color_eyre::Result;
use std::path::Path;
pub fn load_data<T, F: Fn(String) -> Result<T>>(day: u8, parse: F) -> Result<T> {
let s = std::fs::read_to_string(format!("inputs/{day}.txt"))?;
parse(s)
use color_eyre::{eyre::eyre, Result};
pub fn load_data<T, F: Fn(&str) -> Result<T>>(day: u8, parse: F) -> Result<T> {
let s = fetch_input(day)?;
parse(&s)
}
#[macro_export]
macro_rules! data {
($day:expr) => {
$crate::load_data($day, parse)?
};
}
const AOC_SESSION_COOKIE: &str = concat!("session=", env!("AOC_SESSION"));
pub fn fetch_input(day: u8) -> Result<String> {
let cache_dir = Path::new(".aoc-cache");
let cache = cache_dir.join(format!("{day}.txt"));
std::fs::create_dir_all(cache_dir).map_err(|e| eyre!("failed to create cache directory: {e}"))?;
if cache.exists() {
println!("hit! we already have input for day {day}");
std::fs::read_to_string(cache).map_err(|e| eyre!("failed to read input cache: {e}"))
} else {
println!("miss! fetching input for day {day}");
let body: String = ureq::get(&format!("https://adventofcode.com/2022/day/{day}/input"))
.set("Cookie", AOC_SESSION_COOKIE)
.call()?
.into_string()?;
std::fs::write(cache, &body).map_err(|e| eyre!("failed to save input to cache: {e}"))?;
Ok(body)
}
}
pub mod prelude {
pub use super::{data, load_data};
pub use color_eyre::{eyre::eyre, Result};
pub use aoc_proc::aoc;
}

14
test_cases/day_1.txt Normal file
View file

@ -0,0 +1,14 @@
1000
2000
3000
4000
5000
6000
7000
8000
9000
10000