use std::fmt;
#[derive(Clone, Debug, Eq, Hash, PartialEq, Ord, PartialOrd)]
pub struct Date {
date: DateImpl,
}
impl Date {
pub fn new(year: u16, month: u8, day: u8) -> Self {
Self {
date: DateImpl { year, month, day },
}
}
pub fn year(&self) -> u16 {
self.date.year
}
pub fn month(&self) -> u8 {
self.date.month
}
pub fn day(&self) -> u8 {
self.date.day
}
pub fn ymd(&self) -> impl fmt::Display {
let y = self.date.year;
let m = self.date.month;
let d = self.date.day;
format!("{y:04}-{m:02}-{d:02}")
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Ord, PartialOrd)]
struct DateImpl {
year: u16,
month: u8,
day: u8,
}
#[cfg(test)]
mod tests {
use super::*;
use std::cmp::Ordering;
#[yare::parameterized(
zeroes = { Date::new(0, 0, 0), 0, 0, 0 },
one_two_three = { Date::new(1, 2, 3), 1, 2, 3 },
max = { Date::new(u16::MAX, u8::MAX, u8::MAX), u16::MAX, u8::MAX, u8::MAX },
)]
fn create_release_date(date: Date, year: u16, month: u8, day: u8) {
let expected = Date {
date: DateImpl { year, month, day },
};
assert_eq!(date, expected);
}
#[test]
fn compare_year() {
let smaller = Date::new(2000, 1, 1);
let bigger = Date::new(2001, 1, 1);
assert!(smaller < bigger);
assert!(smaller <= bigger);
}
#[test]
fn compare_month() {
let smaller = Date::new(2000, 1, 1);
let bigger = Date::new(2000, 2, 1);
assert!(smaller < bigger);
assert!(smaller <= bigger);
}
#[test]
fn compare_day() {
let smaller = Date::new(2000, 1, 1);
let bigger = Date::new(2000, 1, 2);
assert!(smaller < bigger);
assert!(smaller <= bigger);
}
#[yare::parameterized(
zeroes = { Date::new(0, 0, 0), "0000-00-00" },
fill_y = { Date::new(1, 10, 10), "0001-10-10" },
fill_m = { Date::new(1000, 1, 10), "1000-01-10" },
fill_d = { Date::new(1000, 10, 1), "1000-10-01" },
invalid_month_is_not_rejected = { Date::new(1000, 100, 1), "1000-100-01" },
invalid_day_is_not_rejected = { Date::new(1000, 1, 100), "1000-01-100" },
)]
fn to_string(date: Date, expected: &str) {
assert_eq!(date.ymd().to_string(), expected.to_string());
}
#[test]
fn newer_date() {
let newer = Date::new(2000, 1, 1);
let older = Date::new(1999, 1, 1);
assert_eq!(newer.cmp(&older), Ordering::Greater);
}
}