prepare from last year's setup
This commit is contained in:
commit
ab26e1e1a1
5 changed files with 143 additions and 0 deletions
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
*~
|
||||||
|
\#*#
|
||||||
|
.#*#
|
||||||
|
|
||||||
|
target/
|
||||||
|
Cargo.lock
|
13
Cargo.toml
Normal file
13
Cargo.toml
Normal 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
38
rustfmt.toml
Normal 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
14
src/bin/day1.rs
Normal 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
72
src/lib.rs
Normal 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")
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in a new issue