Skip to content

Instantly share code, notes, and snippets.

@tyhdefu
Created February 7, 2023 09:37
Show Gist options
  • Save tyhdefu/8bc6344160b50913a5d0f88702dfae24 to your computer and use it in GitHub Desktop.
Save tyhdefu/8bc6344160b50913a5d0f88702dfae24 to your computer and use it in GitHub Desktop.
/// YYYY-MM-DD HH:MM:SS
macro_rules! utc_datetime {
($y:tt-$m:tt-$d:tt $H:tt:$M:tt:$S:tt) => {
// Constrain year to the limits of u16::MIN -> u16::MAX, which is well within
// the valid bounds of chrono.
let year: u16 = $y;
// Check day with its corresponding month.
month_day!($m, $d);
time!($H:$M:$S);
};
}
macro_rules! month_day {
(02, 29) => {
compile_error!("Chrono does not currently support compile-time checking of leap years!");
};
(01, $d:tt) => {check_thirty_one_days!($d);};
(02, $d:tt) => {check_common_days!($d);};
(03, $d:tt) => {check_thirty_one_days!($d);};
(04, $d:tt) => {check_thirty_days!($d);};
(05, $d:tt) => {check_thirty_one_days!($d);};
(06, $d:tt) => {check_thirty_days!($d);};
(07, $d:tt) => {check_thirty_one_days!($d);};
(08, $d:tt) => {check_thirty_one_days!($d);};
(09, $d:tt) => {check_thirty_days!($d);};
(10, $d:tt) => {check_thirty_one_days!($d);};
(11, $d:tt) => {check_thirty_days!($d);};
(12, $d:tt) => {check_thirty_one_days!($d);};
($m:tt, $d:tt) => {
compile_error!("Invalid month [01-12]!");
}
}
macro_rules! check_thirty_one_days {
(29) => {};
(30) => {};
(31) => {};
($d:tt) => {
check_common_days!($d);
}
}
macro_rules! check_thirty_days {
(29) => {};
(30) => {};
($d:tt) => {
common_days!($d);
};
}
macro_rules! check_common_days {
(00) => {};
(01) => {};
(02) => {};
(03) => {};
(04) => {};
(05) => {};
(06) => {};
(07) => {};
(08) => {};
(09) => {};
(10) => {};
(11) => {};
(12) => {};
(13) => {};
(14) => {};
(15) => {};
(16) => {};
(17) => {};
(18) => {};
(19) => {};
(20) => {};
(21) => {};
(22) => {};
(23) => {};
(24) => {};
(25) => {};
(26) => {};
(27) => {};
(28) => {};
{$d:expr} => {
let day: u8 = $d;
compile_error!("Not a valid day for the given month");
}
}
/// HH:MM:SS
macro_rules! time {
($H:tt:$M:tt:$S:tt) => {
check_hours!($H);
up_to_59!($M);
up_to_59!($S);
}
}
macro_rules! check_hours {
(00) => {};
(01) => {};
(02) => {};
(03) => {};
(04) => {};
(05) => {};
(06) => {};
(07) => {};
(08) => {};
(09) => {};
(10) => {};
(11) => {};
(12) => {};
(13) => {};
(14) => {};
(15) => {};
(16) => {};
(17) => {};
(18) => {};
(19) => {};
(20) => {};
(21) => {};
(22) => {};
(23) => {};
($h:tt) => {
let hours: u8 = $h; // Constrain to unsigned integer
compile_error!("Hours must be 00-23");
};
}
macro_rules! up_to_59 {
(00) => {};
(01) => {};
(02) => {};
(03) => {};
(04) => {};
(05) => {};
(06) => {};
(07) => {};
(08) => {};
(09) => {};
(10) => {};
(11) => {};
(12) => {};
(13) => {};
(14) => {};
(15) => {};
(16) => {};
(17) => {};
(18) => {};
(19) => {};
(20) => {};
(21) => {};
(22) => {};
(23) => {};
(24) => {};
(25) => {};
(26) => {};
(27) => {};
(28) => {};
(29) => {};
(30) => {};
(31) => {};
(32) => {};
(33) => {};
(34) => {};
(35) => {};
(36) => {};
(37) => {};
(38) => {};
(39) => {};
(40) => {};
(41) => {};
(42) => {};
(43) => {};
(44) => {};
(45) => {};
(46) => {};
(46) => {};
(46) => {};
(47) => {};
(48) => {};
(49) => {};
(50) => {};
(51) => {};
(52) => {};
(53) => {};
(54) => {};
(55) => {};
(56) => {};
(57) => {};
(58) => {};
(59) => {};
($x:literal) => {
let x: u8 = $x; // Constrain to unsigned integer
compile_error!("Either hours or minutes are not 00-59");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment