commit ab26e1e1a1e2fbcd09203af5bb19913216cbfef9 Author: Dominic Date: Thu Nov 30 19:08:08 2023 +0100 prepare from last year's setup diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..535cc56 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*~ +\#*# +.#*# + +target/ +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..ae7ba3c --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "aoc23" +version = "0.0.0" +publish = false +edition = "2021" + +[dependencies] +anyhow = "1" +ariadne = "0.1" +bit-vec = "0.6" +chumsky = "0.8" +indexmap = "1.9" +paste = "1.0" diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..62f400e --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,38 @@ +edition = "2021" +max_width = 90 +newline_style = "Unix" +unstable_features = true + +# skip generated files +format_generated_files = false + +# always use tabs. +hard_tabs = true +tab_spaces = 4 + +# commas inbetween but not after +match_block_trailing_comma = true +trailing_comma = "Never" + +# fix my imports for me +imports_granularity = "Crate" +#group_imports = "One" + +# format everything +format_code_in_doc_comments = true +format_macro_matchers = true + +# don't keep outdated syntax +use_field_init_shorthand = true +use_try_shorthand = true + +# condense Struct { _, _ } to Struct { .. } +condense_wildcard_suffixes = true + +# prefer foo(Bar { \n }) over foo(\nBar { \n }\n) +overflow_delimited_expr = true + +# I wish there was a way to allow 0..n but not a + 1..b + 2 +# However, the later looks so terible that I use spaces everywhere +# https://github.com/rust-lang/rustfmt/issues/3367 +spaces_around_ranges = true diff --git a/src/bin/day1.rs b/src/bin/day1.rs new file mode 100644 index 0000000..246399d --- /dev/null +++ b/src/bin/day1.rs @@ -0,0 +1,14 @@ +#![forbid(elided_lifetimes_in_paths, unsafe_code)] + +use aoc23::read; +use chumsky::prelude::*; + +fn parser() -> impl Parser> { + end() +} + +fn main() -> anyhow::Result<()> { + let _ = read("input.txt", parser())?; + + Ok(()) +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..f1d53fb --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,72 @@ +use anyhow::{anyhow, Context}; +use ariadne::{Label, Report, ReportKind, Source}; +use chumsky::{error::SimpleReason, prelude::*}; +use std::{fs, path::Path}; + +fn report_err(buf: &str, path_str: &str, err: Vec>) { + for e in err { + let mut report = Report::build(ReportKind::Error, path_str, e.span().start); + match (e.reason(), e.found()) { + (SimpleReason::Unexpected, Some(found)) => { + report.set_message("Unexpected token"); + report.add_label( + Label::new((path_str, e.span())) + .with_message(format!("Unexpected token {found}")) + ); + if e.expected().len() > 0 { + report.set_note(format!( + "Expected {}", + e.expected() + .map(|ex| match ex { + Some(ex) => format!("{ex:?}"), + None => "end of file".to_owned() + }) + .collect::>() + .join(", ") + )); + } + }, + + (SimpleReason::Unexpected, None) => { + report.set_message("Unexpected end of file"); + }, + + (SimpleReason::Unclosed { span, delimiter }, found) => { + report.set_message("Unclosed delimiter"); + report.add_label( + Label::new((path_str, span.clone())) + .with_message(format!("Unclosed delimiter {}", delimiter)) + ); + if let Some(found) = found { + report.add_label( + Label::new((path_str, e.span())) + .with_message(format!("Must be closed before this {found}")) + ); + } + }, + + (SimpleReason::Custom(msg), _) => { + report.set_message(msg); + report.add_label(Label::new((path_str, e.span())).with_message(msg)); + } + }; + report + .finish() + .print((path_str, Source::from(buf))) + .unwrap() + } +} + +pub fn read(path: P, parser: C) -> anyhow::Result +where + P: AsRef, + C: Parser> +{ + let path = path.as_ref(); + let buf = fs::read_to_string(path) + .with_context(|| format!("Failed to read {}", path.display()))?; + parser.parse(buf.as_str()).map_err(|errors| { + report_err(&buf, &path.to_string_lossy(), errors); + anyhow!("Failed to parse input") + }) +}