Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ test_lib = []

# Template dependencies
chrono = { version = "0.4.38", optional = true }
const-str = "0.7.0"
dhat = { version = "0.3.3", optional = true }
pico-args = "0.5.0"
tinyjson = "2.5.1"
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ fn main() {
None => {
eprintln!(
"`today` command can only be run between the 1st and \
the 25th of december. Please use `scaffold` with a specific day."
the 12th of december. Please use `scaffold` with a specific day."
);
process::exit(1)
}
Expand Down
59 changes: 36 additions & 23 deletions src/template/day.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ use chrono::{Datelike, FixedOffset, Utc};
#[cfg(feature = "today")]
const SERVER_UTC_OFFSET: i32 = -5;

/// A valid day number of advent (i.e. an integer in range 1 to 25).
/// A valid day number of advent (i.e. an integer in range 1 to 12).
/// Before the year 2025, allow integers up to 25.
///
/// # Display
/// This value displays as a two digit number.
Expand All @@ -21,11 +22,20 @@ const SERVER_UTC_OFFSET: i32 = -5;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Day(u8);

macro_rules! day_count {
() => {
match const_str::parse!(env!("AOC_YEAR"), u16) < 2025 {
true => 25u8,
false => 12u8,
}
}
}

impl Day {
/// Creates a [`Day`] from the provided value if it's in the valid range,
/// returns [`None`] otherwise.
pub const fn new(day: u8) -> Option<Self> {
if day == 0 || day > 25 {
if day == 0 || day > day_count!() {
return None;
}
Some(Self(day))
Expand All @@ -39,11 +49,12 @@ impl Day {

#[cfg(feature = "today")]
impl Day {
/// Returns the current day if it's between the 1st and the 25th of december, `None` otherwise.
/// Returns the current day if it's between the 1st and the 12th of december, `None` otherwise.
/// Accepts days up to the 25th if the Year is before 2025.
pub fn today() -> Option<Self> {
let offset = FixedOffset::east_opt(SERVER_UTC_OFFSET * 3600)?;
let today = Utc::now().with_timezone(&offset);
if today.month() == 12 && today.day() <= 25 {
if today.month() == 12 && today.day() <= day_count!() as u32 {
Self::new(u8::try_from(today.day()).ok()?)
} else {
None
Expand Down Expand Up @@ -88,18 +99,18 @@ 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")
f.write_str(&format!("expecting a day number between 1 and {}", day_count!()))
}
}

/* -------------------------------------------------------------------------- */

/// An iterator that yields every day of advent from the 1st to the 25th.
/// An iterator that yields every day of advent from the 1st to the 12th (or 25th before 2025).
pub fn all_days() -> AllDays {
AllDays::new()
}

/// An iterator that yields every day of advent from the 1st to the 25th.
/// An iterator that yields every day of advent from the 1st to the 12th (or 25th before 2025).
pub struct AllDays {
current: u8,
}
Expand All @@ -115,10 +126,10 @@ impl Iterator for AllDays {
type Item = Day;

fn next(&mut self) -> Option<Self::Item> {
if self.current > 25 {
if self.current > day_count!() {
return None;
}
// NOTE: the iterator starts at 1 and we have verified that the value is not above 25.
// NOTE: the iterator starts at 1, and we have verified that the value is not above 12 (or 25).
let day = Day(self.current);
self.current += 1;

Expand All @@ -134,7 +145,7 @@ macro_rules! day {
($day:expr) => {
const {
$crate::template::Day::new($day)
.expect("invalid day number, expecting a value between 1 and 25")
.expect("invalid day number, expecting a value between 1 and 12 (or 25 before 2025)")
}
};
}
Expand All @@ -161,19 +172,21 @@ mod tests {
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)));
if day_count!() > 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);
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/template/timings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ mod tests {
}],
};

assert_eq!(timings.is_day_complete(&day!(1)), true);
assert_eq!(timings.is_day_complete(day!(1)), true);
}

#[test]
Expand All @@ -299,7 +299,7 @@ mod tests {
}],
};

assert_eq!(timings.is_day_complete(&day!(1)), false);
assert_eq!(timings.is_day_complete(day!(1)), false);
}

#[test]
Expand All @@ -313,7 +313,7 @@ mod tests {
}],
};

assert_eq!(timings.is_day_complete(&day!(1)), false);
assert_eq!(timings.is_day_complete(day!(1)), false);
}
}

Expand Down