use std::fmt;
use jiff::civil::Weekday;
const ALL_DAYS: [Weekday; 7] = [
Weekday::Monday,
Weekday::Tuesday,
Weekday::Wednesday,
Weekday::Thursday,
Weekday::Friday,
Weekday::Saturday,
Weekday::Sunday,
];
#[derive(Clone, Copy, Default, PartialEq, Eq, Hash)]
pub struct Weekdays(u8);
impl Weekdays {
pub const EMPTY: Self = Self(0);
pub const MON_TO_FRI: Self = Self(0b001_1111);
pub const ALL: Self = Self(0b111_1111);
#[must_use]
pub fn contains(self, day: Weekday) -> bool {
self.0 & bit(day) != 0
}
#[must_use]
pub fn is_empty(self) -> bool {
self.0 == 0
}
}
fn bit(day: Weekday) -> u8 {
1 << day.to_monday_zero_offset()
}
impl FromIterator<Weekday> for Weekdays {
fn from_iter<I: IntoIterator<Item = Weekday>>(days: I) -> Self {
Self(days.into_iter().fold(0, |set, day| set | bit(day)))
}
}
impl fmt::Debug for Weekdays {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_set()
.entries(ALL_DAYS.into_iter().filter(|&day| self.contains(day)))
.finish()
}
}
#[cfg(test)]
mod tests {
use jiff::civil::Weekday;
use super::{Weekdays, ALL_DAYS};
#[test]
fn constants_match_their_days() {
assert_eq!(Weekdays::ALL, ALL_DAYS.into_iter().collect());
assert_eq!(
Weekdays::MON_TO_FRI,
ALL_DAYS[..5].iter().copied().collect()
);
assert_eq!(Weekdays::EMPTY, std::iter::empty().collect());
assert_eq!(Weekdays::default(), Weekdays::EMPTY);
}
#[test]
fn duplicates_collapse() {
let days: Weekdays = [Weekday::Monday, Weekday::Monday].into_iter().collect();
assert_eq!(format!("{days:?}"), "{Monday}");
}
#[test]
fn debug_lists_days_from_monday() {
let days: Weekdays = [Weekday::Sunday, Weekday::Wednesday].into_iter().collect();
assert_eq!(format!("{days:?}"), "{Wednesday, Sunday}");
}
}