feat: some cursed proc macro stuff to improve actual solution code
This commit is contained in:
parent
b60e991f6d
commit
a008c64177
12 changed files with 781 additions and 10 deletions
2
.envrc
Normal file
2
.envrc
Normal file
|
@ -0,0 +1,2 @@
|
|||
use flake
|
||||
dotenv
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1 +1,3 @@
|
|||
/target
|
||||
.env
|
||||
/.direnv
|
||||
|
|
348
Cargo.lock
generated
348
Cargo.lock
generated
|
@ -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"
|
||||
|
|
|
@ -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
13
aoc_proc/Cargo.toml
Normal 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
150
aoc_proc/src/lib.rs
Normal 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
123
flake.lock
Normal 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
79
flake.nix
Normal 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
|
||||
];
|
||||
};
|
||||
});
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
44
src/lib.rs
44
src/lib.rs
|
@ -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
14
test_cases/day_1.txt
Normal file
|
@ -0,0 +1,14 @@
|
|||
1000
|
||||
2000
|
||||
3000
|
||||
|
||||
4000
|
||||
|
||||
5000
|
||||
6000
|
||||
|
||||
7000
|
||||
8000
|
||||
9000
|
||||
|
||||
10000
|
Loading…
Reference in a new issue