diff --git a/2023/Cargo.lock b/2023/Cargo.lock index f265292..18bf40c 100644 --- a/2023/Cargo.lock +++ b/2023/Cargo.lock @@ -140,6 +140,7 @@ dependencies = [ "log", "nom", "test-log", + "thiserror", ] [[package]] @@ -246,9 +247,12 @@ dependencies = [ name = "day-2" version = "2023.0.0" dependencies = [ + "error-stack", "itertools 0.12.0", "log", "nom", + "test-log", + "thiserror", ] [[package]] @@ -384,7 +388,7 @@ dependencies = [ "proc-macro2", "quote", "semver", - "syn 2.0.39", + "syn 2.0.47", ] [[package]] @@ -507,7 +511,7 @@ checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.47", ] [[package]] @@ -895,18 +899,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.70" +version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "907a61bd0f64c2f29cd1cf1dc34d05176426a3f504a78010f08416ddb7b13708" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -1050,7 +1054,7 @@ dependencies = [ "regex", "relative-path", "rustc_version", - "syn 2.0.39", + "syn 2.0.47", "unicode-ident", ] @@ -1063,7 +1067,7 @@ dependencies = [ "quote", "rand", "rustc_version", - "syn 2.0.39", + "syn 2.0.47", ] [[package]] @@ -1141,7 +1145,7 @@ checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.47", ] [[package]] @@ -1183,9 +1187,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.39" +version = "2.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "1726efe18f42ae774cc644f330953a5e7b3c3003d3edcecf18850fe9d4dd9afb" dependencies = [ "proc-macro2", "quote", @@ -1220,27 +1224,27 @@ checksum = "7ba277e77219e9eea169e8508942db1bf5d8a41ff2db9b20aab5a5aadc9fa25d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.47", ] [[package]] name = "thiserror" -version = "1.0.51" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f11c217e1416d6f036b870f14e0413d480dbf28edbee1f877abaf0206af43bb7" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.51" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01742297787513b79cf8e29d1056ede1313e2420b7b3b15d0a768b4921f549df" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.47", ] [[package]] @@ -1341,5 +1345,5 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.47", ] diff --git a/2023/Cargo.toml b/2023/Cargo.toml index 2abab2b..99d8b8e 100644 --- a/2023/Cargo.toml +++ b/2023/Cargo.toml @@ -25,6 +25,7 @@ num-traits = "0.2.17" rustworkx-core = "0.13.2" pathfinding = "4.8.0" test-log = {version="0.2.14", features=["default", "unstable"]} +thiserror = "1.0.56" [profile.dhat] diff --git a/2023/day-1/Cargo.toml b/2023/day-1/Cargo.toml index 7ca8ea0..4c5fc8e 100644 --- a/2023/day-1/Cargo.toml +++ b/2023/day-1/Cargo.toml @@ -14,6 +14,7 @@ error-stack.workspace = true itertools.workspace = true log.workspace = true nom.workspace = true +thiserror.workspace = true [dev-dependencies] test-log = {workspace=true} diff --git a/2023/day-1/src/main.rs b/2023/day-1/src/main.rs index e4db865..3e02b2c 100644 --- a/2023/day-1/src/main.rs +++ b/2023/day-1/src/main.rs @@ -3,10 +3,22 @@ use day_1::part1::part1; use day_1::part2::part2; -fn main() { - let input = include_str!("./input.txt"); - let part1_result = part1(input).unwrap(); - println!("part 1: {part1_result}"); - let part2_result = part2(input).unwrap(); - println!("part 2: {part2_result}"); +use error_stack::{Result, ResultExt}; +use thiserror::Error; + +#[derive(Debug, Error)] +enum Day1Error { + #[error("Part 1 failed")] + Part1Error, + #[error("Part 2 failed")] + Part2Error, +} + +fn main() -> Result<(), Day1Error> { + let input = include_str!("./input.txt"); + let part1_result = part1(input).change_context(Day1Error::Part1Error)?; + println!("part 1: {part1_result}"); + let part2_result = part2(input).change_context(Day1Error::Part2Error)?; + println!("part 2: {part2_result}"); + Ok(()) } diff --git a/2023/day-1/src/part1.rs b/2023/day-1/src/part1.rs index bd3bc56..0840369 100644 --- a/2023/day-1/src/part1.rs +++ b/2023/day-1/src/part1.rs @@ -1,7 +1,5 @@ #![warn(clippy::all, clippy::pedantic)] -use std::fmt::Display; - use log::trace; use nom::{ self, @@ -9,17 +7,15 @@ use nom::{ multi::separated_list1, }; -use error_stack::{Context, Report, Result, ResultExt}; +use error_stack::{Report, Result, ResultExt}; +use thiserror::Error; -#[derive(Debug)] -pub struct Day1Part1Error; - -impl Context for Day1Part1Error {} - -impl Display for Day1Part1Error { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "day 1 part 1 error") - } +#[derive(Debug, Error)] +pub enum Day1Part1Error { + #[error("Problem parsing Day 1")] + ParseError, + #[error("Day 1 Input parsed to Empty")] + EmptyInput, } /// Day-1 part 1 of AC2023 @@ -32,21 +28,16 @@ impl Display for Day1Part1Error { pub fn part1(input: &str) -> Result { let (_input, values) = parse_input(input) .map_err(|x| Report::from(x.to_owned())) - .change_context(Day1Part1Error)?; + .change_context(Day1Part1Error::ParseError)?; trace!("{values:?}"); values .iter() .map(|v| { v.first() .and_then(|first| v.last().map(|last| *first * 10 + *last)) - .ok_or(Day1Part1Error) - }) - .try_fold(0_u32, |sum, number| { - let Ok(number) = number else { - return Err(Report::from(Day1Part1Error)); - }; - Ok(sum + number) + .ok_or(Day1Part1Error::EmptyInput) }) + .try_fold(0_u32, |sum, number| Ok(sum + number?)) .map(|x| x.to_string()) } diff --git a/2023/day-1/src/part2.rs b/2023/day-1/src/part2.rs index 1fcb81f..3bef3bc 100644 --- a/2023/day-1/src/part2.rs +++ b/2023/day-1/src/part2.rs @@ -1,19 +1,17 @@ #![warn(clippy::all, clippy::pedantic)] -use std::{fmt::Display, ops::Not}; +use std::ops::Not; -use error_stack::{Context, Report, Result}; +use error_stack::{report, Result}; use log::trace; +use thiserror::Error; -#[derive(Debug)] -pub struct Day1Part2Error; - -impl Context for Day1Part2Error {} - -impl Display for Day1Part2Error { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "day 1 part 2 error") - } +#[derive(Debug, Error)] +pub enum Day1Part2Error { + #[error("Problem parsing Day-1 Part2")] + ParseError, + #[error("Day 1 Input parsed to Empty")] + EmptyInput, } /// Day 1 Part 2 of AOC2023 @@ -34,14 +32,9 @@ pub fn part2(input: &str) -> Result { .map(|v| { v.first() .and_then(|first| v.last().map(|last| *first * 10 + *last)) - .ok_or(Day1Part2Error) - }) - .try_fold(0_u32, |sum, number| { - let Ok(number) = number else { - return Err(Report::from(Day1Part2Error)); - }; - Ok(sum + number) + .ok_or(report!(Day1Part2Error::EmptyInput)) }) + .try_fold(0_u32, |sum, number| Ok(sum + number?)) .map(|x| x.to_string()) } @@ -80,7 +73,7 @@ fn parse_line(line: &str) -> Result, Day1Part2Error> { .is_empty() .not() .then_some(numbers) - .ok_or(Report::from(Day1Part2Error)) + .ok_or(report!(Day1Part2Error::ParseError)) } #[cfg(test)] diff --git a/2023/day-2/Cargo.toml b/2023/day-2/Cargo.toml index ed23618..199f72e 100644 --- a/2023/day-2/Cargo.toml +++ b/2023/day-2/Cargo.toml @@ -11,3 +11,8 @@ repository.workspace = true nom.workspace = true itertools.workspace = true log.workspace = true +error-stack.workspace = true +thiserror.workspace = true + +[dev-dependencies] +test-log.workspace = true diff --git a/2023/day-2/src/main.rs b/2023/day-2/src/main.rs index 5950776..0075c8d 100644 --- a/2023/day-2/src/main.rs +++ b/2023/day-2/src/main.rs @@ -3,10 +3,22 @@ use day_2::part1; use day_2::part2; -fn main() { - let input = include_str!("./input.txt"); - let part1_result = part1(input); - println!("part 1: {part1_result}"); - let part2_result = part2(input); - println!("part 2: {part2_result}"); +use error_stack::{Result, ResultExt}; +use thiserror::Error; + +#[derive(Debug, Error)] +enum Day2Error { + #[error("Part 1 failed")] + Part1Error, + #[error("Part 2 failed")] + Part2Error, +} + +fn main() -> Result<(), Day2Error> { + let input = include_str!("./input.txt"); + let part1_result = part1(input).change_context(Day2Error::Part1Error)?; + println!("part 1: {part1_result}"); + let part2_result = part2(input).change_context(Day2Error::Part2Error)?; + println!("part 2: {part2_result}"); + Ok(()) } diff --git a/2023/day-2/src/part1.rs b/2023/day-2/src/part1.rs index 7fd9088..c9b87b8 100644 --- a/2023/day-2/src/part1.rs +++ b/2023/day-2/src/part1.rs @@ -1,5 +1,6 @@ #![warn(clippy::all, clippy::pedantic)] +use error_stack::{Report, Result, ResultExt}; use log::debug; use nom::{ bytes::complete::tag, @@ -7,6 +8,13 @@ use nom::{ multi::separated_list1, sequence::{preceded, separated_pair}, }; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum Day2Part1Error { + #[error("there was a problem parsing")] + ParseError, +} #[derive(Debug)] struct Round { @@ -23,8 +31,7 @@ struct Game { impl Game { fn to_part1(&self) -> Option { - if self - .rounds + self.rounds .iter() .find_map(|r| { //TODO if inverted use find_map @@ -34,12 +41,8 @@ impl Game { None } }) - .is_some() - { - None - } else { - Some(self.id) - } + .is_none() + .then_some(self.id) } } @@ -48,16 +51,18 @@ impl Game { /// # Arguments /// - input the puszzle input /// -/// # Panics -/// panics whenever the input isn't parsable -pub fn part1(input: &str) -> String { - let (_, games) = process_input(input).expect("there should be input"); +/// # Errors +/// errors whenever the input isn't parsable +pub fn part1(input: &'static str) -> Result { + let (_, games) = process_input(input) + .map_err(|err| Report::from(err.to_owned())) + .change_context(Day2Part1Error::ParseError)?; debug!("{games:?}"); - games + Ok(games .iter() .filter_map(Game::to_part1) .sum::() - .to_string() + .to_string()) } fn process_block(input: &str) -> nom::IResult<&str, (u32, String)> { @@ -107,9 +112,10 @@ Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green"; - #[test] + #[test_log::test] + #[test_log(default_log_filter = "trace")] fn part1_works() { - let result = part1(INPUT); + let result = part1(INPUT).unwrap(); assert_eq!(result, "8".to_string()); } } diff --git a/2023/day-2/src/part2.rs b/2023/day-2/src/part2.rs index ea4a794..a6cbe15 100644 --- a/2023/day-2/src/part2.rs +++ b/2023/day-2/src/part2.rs @@ -1,11 +1,19 @@ #![warn(clippy::all, clippy::pedantic)] +use error_stack::{Report, Result, ResultExt}; use nom::{ bytes::complete::tag, character::complete::{self, newline}, multi::separated_list1, sequence::{preceded, separated_pair}, }; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum Day2Part2Error { + #[error("there was a problem parsing")] + ParseError, +} #[derive(Debug)] struct Round { @@ -44,11 +52,13 @@ impl Game { /// # Arguments /// - input the puszzle input /// -/// # Panics -/// panics whenever the input isn't parsable -pub fn part2(input: &str) -> String { - let (_, games) = process_input(input).expect("there should be input"); - games.iter().map(Game::to_power).sum::().to_string() +/// # Errors +/// errors whenever the input isn't parsable +pub fn part2(input: &str) -> Result { + let (_, games) = process_input(input) + .map_err(|err| Report::from(err.to_owned())) + .change_context(Day2Part2Error::ParseError)?; //expect("there should be input"); + Ok(games.iter().map(Game::to_power).sum::().to_string()) } fn process_block(input: &str) -> nom::IResult<&str, (u32, String)> { @@ -98,9 +108,10 @@ Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green"; - #[test] + #[test_log::test] + #[test_log(default_log_filter = "trace")] fn part2_works() { - let result = part2(INPUT); + let result = part2(INPUT).unwrap(); assert_eq!(result, "2286".to_string()); } }