Skip to content

Instantly share code, notes, and snippets.

@reu
Last active March 15, 2023 14:02
Show Gist options
  • Save reu/04473f4d21333696aec82384fb717469 to your computer and use it in GitHub Desktop.
Save reu/04473f4d21333696aec82384fb717469 to your computer and use it in GitHub Desktop.
Operator overloading for building dates in Rust (don't, just don´t)
use std::ops::{Div, Sub};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum Month {
Jan = 1,
Feb = 2,
Mar = 3,
Apr = 4,
Mai = 5,
Jun = 6,
Jul = 7,
Aug = 8,
Sep = 9,
Oct = 10,
Nov = 11,
Dez = 12,
}
pub use Month::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct MonthDay(Month, u8);
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct YearMonth(i32, Month);
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Date {
pub year: i32,
pub month: Month,
pub day: u8,
}
impl Date {
pub fn from_ymd(year: i32, month: Month, day: u8) -> Self {
Date { day, month, year }
}
}
impl Div<Month> for u8 {
type Output = MonthDay;
fn div(self, month: Month) -> Self::Output {
MonthDay(month, self)
}
}
impl Div<u8> for Month {
type Output = MonthDay;
fn div(self, day: u8) -> Self::Output {
MonthDay(self, day)
}
}
impl Div<i32> for MonthDay {
type Output = Date;
fn div(self, year: i32) -> Self::Output {
Date::from_ymd(year, self.0, self.1)
}
}
impl Sub<Month> for i32 {
type Output = YearMonth;
fn sub(self, rhs: Month) -> Self::Output {
YearMonth(self, rhs)
}
}
impl Sub<u8> for YearMonth {
type Output = Date;
fn sub(self, day: u8) -> Self::Output {
Date::from_ymd(self.0, self.1, day)
}
}
#[test]
fn test_iso() {
assert_eq!(1986 - Mar - 31, Date::from_ymd(1986, Mar, 31));
}
#[test]
fn test_dmy() {
assert_eq!(31 / Mar / 1986, Date::from_ymd(1986, Mar, 31));
}
#[test]
fn test_mdy() {
assert_eq!(Mar / 31 / 1986, Date::from_ymd(1986, Mar, 31));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment