-
Notifications
You must be signed in to change notification settings - Fork 61
Add a Day type to provide better handling of day value #35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 11 commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
da04cb7
implement Day newtype
tguichaoua 674c9cc
fix tests
tguichaoua dc579bf
add some docs
tguichaoua 05edf3a
add test for the iterator
tguichaoua cbc44bf
update day error string
tguichaoua ecbe5f2
fix doc code
tguichaoua e60222a
update code template
tguichaoua 27c29d7
fix typo
tguichaoua 3b1c466
fix test
tguichaoua 2e223f9
refactor test
tguichaoua e3d77e5
use day! macros instead of new + unwrap
tguichaoua 24ab444
Update src/day.rs
tguichaoua bc9b0e2
Update src/day.rs
tguichaoua 0e6ee20
Update src/day.rs
tguichaoua e73285f
Update src/day.rs
tguichaoua 94c5a48
rename EveryDay into AllDays
tguichaoua 8469726
rename test
tguichaoua File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
use std::error::Error; | ||
use std::fmt::Display; | ||
use std::str::FromStr; | ||
|
||
/* -------------------------------------------------------------------------- */ | ||
|
||
/// A valid day number of advent (i.e. an integer in range 1 to 25). | ||
/// | ||
/// # Display | ||
/// This value is display as a two digit number. | ||
tguichaoua marked this conversation as resolved.
Show resolved
Hide resolved
|
||
/// | ||
/// ``` | ||
/// # use advent_of_code::Day; | ||
/// let day = Day::new(8).unwrap(); | ||
/// assert_eq!(day.to_string(), "08") | ||
/// ``` | ||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
pub struct Day(u8); | ||
|
||
impl Day { | ||
/// Creates a [`Day`] from the provided value if it's in the valid range, | ||
/// returns [`None`] otherwise. | ||
pub fn new(day: u8) -> Option<Self> { | ||
if day == 0 || day > 25 { | ||
return None; | ||
} | ||
Some(Self(day)) | ||
} | ||
|
||
// Not part of the public API | ||
#[doc(hidden)] | ||
pub const fn __new_unchecked(day: u8) -> Self { | ||
Self(day) | ||
} | ||
|
||
/// Converts the [`Day`] into an [`u8`]. | ||
pub fn into_inner(self) -> u8 { | ||
self.0 | ||
} | ||
} | ||
|
||
impl Display for Day { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
write!(f, "{:02}", self.0) | ||
} | ||
} | ||
|
||
impl PartialEq<u8> for Day { | ||
fn eq(&self, other: &u8) -> bool { | ||
self.0.eq(other) | ||
} | ||
} | ||
|
||
impl PartialOrd<u8> for Day { | ||
fn partial_cmp(&self, other: &u8) -> Option<std::cmp::Ordering> { | ||
self.0.partial_cmp(other) | ||
} | ||
} | ||
|
||
/* -------------------------------------------------------------------------- */ | ||
|
||
impl FromStr for Day { | ||
type Err = DayFromStrError; | ||
|
||
fn from_str(s: &str) -> Result<Self, Self::Err> { | ||
let day = s.parse().map_err(|_| DayFromStrError)?; | ||
Self::new(day).ok_or(DayFromStrError) | ||
} | ||
} | ||
|
||
/// An error which can be returned when parsing a [`Day`]. | ||
#[derive(Debug)] | ||
pub struct DayFromStrError; | ||
|
||
impl Error for DayFromStrError {} | ||
|
||
impl Display for DayFromStrError { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
f.write_str("expecting a day number between 1 and 25") | ||
} | ||
} | ||
|
||
/* -------------------------------------------------------------------------- */ | ||
|
||
/// An iterator that yield every day of advent from the 1st to the 25th. | ||
tguichaoua marked this conversation as resolved.
Show resolved
Hide resolved
|
||
pub fn every_day() -> EveryDay { | ||
tguichaoua marked this conversation as resolved.
Show resolved
Hide resolved
|
||
EveryDay { current: 1 } | ||
} | ||
|
||
/// An iterator that yield every day of advent from the 1st to the 25th. | ||
pub struct EveryDay { | ||
current: u8, | ||
} | ||
|
||
impl Iterator for EveryDay { | ||
type Item = Day; | ||
|
||
fn next(&mut self) -> Option<Self::Item> { | ||
if self.current > 25 { | ||
return None; | ||
} | ||
// NOTE: the iterator start at 1 and we have verified that the value is not above 25. | ||
tguichaoua marked this conversation as resolved.
Show resolved
Hide resolved
|
||
let day = Day(self.current); | ||
self.current += 1; | ||
|
||
Some(day) | ||
} | ||
} | ||
|
||
/* -------------------------------------------------------------------------- */ | ||
|
||
/// Creates a [`Day`] value in a const context. | ||
#[macro_export] | ||
macro_rules! day { | ||
($day:expr) => {{ | ||
const _ASSERT: () = assert!( | ||
$day != 0 && $day <= 25, | ||
concat!( | ||
"invalid day number `", | ||
$day, | ||
"`, expecting a value between 1 and 25" | ||
), | ||
); | ||
$crate::Day::__new_unchecked($day) | ||
}}; | ||
} | ||
|
||
/* -------------------------------------------------------------------------- */ | ||
|
||
#[cfg(feature = "test_lib")] | ||
mod tests { | ||
use super::{every_day, Day}; | ||
|
||
#[test] | ||
fn every_day_iterator() { | ||
let mut iter = every_day(); | ||
|
||
assert_eq!(iter.next(), Some(Day(1))); | ||
assert_eq!(iter.next(), Some(Day(2))); | ||
assert_eq!(iter.next(), Some(Day(3))); | ||
assert_eq!(iter.next(), Some(Day(4))); | ||
assert_eq!(iter.next(), Some(Day(5))); | ||
assert_eq!(iter.next(), Some(Day(6))); | ||
assert_eq!(iter.next(), Some(Day(7))); | ||
assert_eq!(iter.next(), Some(Day(8))); | ||
assert_eq!(iter.next(), Some(Day(9))); | ||
assert_eq!(iter.next(), Some(Day(10))); | ||
assert_eq!(iter.next(), Some(Day(11))); | ||
assert_eq!(iter.next(), Some(Day(12))); | ||
assert_eq!(iter.next(), Some(Day(13))); | ||
assert_eq!(iter.next(), Some(Day(14))); | ||
assert_eq!(iter.next(), Some(Day(15))); | ||
assert_eq!(iter.next(), Some(Day(16))); | ||
assert_eq!(iter.next(), Some(Day(17))); | ||
assert_eq!(iter.next(), Some(Day(18))); | ||
assert_eq!(iter.next(), Some(Day(19))); | ||
assert_eq!(iter.next(), Some(Day(20))); | ||
assert_eq!(iter.next(), Some(Day(21))); | ||
assert_eq!(iter.next(), Some(Day(22))); | ||
assert_eq!(iter.next(), Some(Day(23))); | ||
assert_eq!(iter.next(), Some(Day(24))); | ||
assert_eq!(iter.next(), Some(Day(25))); | ||
assert_eq!(iter.next(), None); | ||
} | ||
} | ||
|
||
/* -------------------------------------------------------------------------- */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,4 @@ | ||
mod day; | ||
pub mod template; | ||
|
||
pub use day::*; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.