prepare from last year's setup

This commit is contained in:
Dominic 2023-11-30 19:08:08 +01:00
commit ab26e1e1a1
Signed by: msrd0
GPG key ID: DCC8C247452E98F9
5 changed files with 143 additions and 0 deletions

6
.gitignore vendored Normal file
View file

@ -0,0 +1,6 @@
*~
\#*#
.#*#
target/
Cargo.lock

13
Cargo.toml Normal file
View file

@ -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"

38
rustfmt.toml Normal file
View file

@ -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

14
src/bin/day1.rs Normal file
View file

@ -0,0 +1,14 @@
#![forbid(elided_lifetimes_in_paths, unsafe_code)]
use aoc23::read;
use chumsky::prelude::*;
fn parser() -> impl Parser<char, (), Error = Simple<char>> {
end()
}
fn main() -> anyhow::Result<()> {
let _ = read("input.txt", parser())?;
Ok(())
}

72
src/lib.rs Normal file
View file

@ -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<Simple<char>>) {
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::<Vec<_>>()
.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<P, C, T>(path: P, parser: C) -> anyhow::Result<T>
where
P: AsRef<Path>,
C: Parser<char, T, Error = Simple<char>>
{
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")
})
}