wiwi/
cron.rs

1use crate::prelude::*;
2
3#[derive(Clone)]
4pub struct CronSchedule {
5	minute: Minute,
6	hour: Hour,
7	day_of_month: DayOfMonth,
8	month: Month,
9	day_of_week: DayOfWeek
10}
11
12impl CronSchedule {
13	/// Creates a blank cron schedule (equivalent to `* * * * *`)
14	#[inline]
15	pub const fn new() -> Self {
16		Self {
17			minute: Minute::new(),
18			hour: Hour::new(),
19			day_of_month: DayOfMonth::new(),
20			month: Month::new(),
21			day_of_week: DayOfWeek::new()
22		}
23	}
24
25	#[inline]
26	pub const fn add_minute(&mut self, minute: u64) {
27		self.minute.add(minute);
28	}
29
30	#[inline]
31	pub const fn add_minute_range(&mut self, e1: u64, e2: u64) {
32		self.minute.add_range(e1, e2);
33	}
34
35	#[inline]
36	pub const fn add_minute_step(&mut self, step: u64) {
37		self.minute.add_step(step);
38	}
39
40	#[inline]
41	pub const fn add_minute_range_step(&mut self, e1: u64, e2: u64, step: u64) {
42		self.minute.add_range_step(e1, e2, step);
43	}
44
45	#[inline]
46	pub const fn add_hour(&mut self, hour: u64) {
47		self.hour.add(hour);
48	}
49
50	#[inline]
51	pub const fn add_hour_range(&mut self, e1: u64, e2: u64) {
52		self.hour.add_range(e1, e2);
53	}
54
55	#[inline]
56	pub const fn add_hour_step(&mut self, step: u64) {
57		self.hour.add_step(step);
58	}
59
60	#[inline]
61	pub const fn add_hour_range_step(&mut self, e1: u64, e2: u64, step: u64) {
62		self.hour.add_range_step(e1, e2, step);
63	}
64
65	#[inline]
66	pub const fn add_day_of_month(&mut self, day_of_month: u64) {
67		self.day_of_month.add(day_of_month);
68	}
69
70	#[inline]
71	pub const fn add_day_of_month_range(&mut self, e1: u64, e2: u64) {
72		self.day_of_month.add_range(e1, e2);
73	}
74
75	#[inline]
76	pub const fn add_day_of_month_step(&mut self, step: u64) {
77		self.day_of_month.add_step(step);
78	}
79
80	#[inline]
81	pub const fn add_day_of_month_range_step(&mut self, e1: u64, e2: u64, step: u64) {
82		self.day_of_month.add_range_step(e1, e2, step);
83	}
84
85	#[inline]
86	pub const fn add_month(&mut self, month: u64) {
87		self.month.add(month);
88	}
89
90	#[inline]
91	pub const fn add_month_range(&mut self, e1: u64, e2: u64) {
92		self.month.add_range(e1, e2);
93	}
94
95	#[inline]
96	pub const fn add_month_step(&mut self, step: u64) {
97		self.month.add_step(step);
98	}
99
100	#[inline]
101	pub const fn add_month_range_step(&mut self, e1: u64, e2: u64, step: u64) {
102		self.month.add_range_step(e1, e2, step);
103	}
104
105	#[inline]
106	pub const fn add_day_of_week(&mut self, day_of_week: u64) {
107		self.day_of_week.add(day_of_week);
108	}
109
110	#[inline]
111	pub const fn add_day_of_week_range(&mut self, e1: u64, e2: u64) {
112		self.day_of_week.add_range(e1, e2);
113	}
114
115	#[inline]
116	pub const fn add_day_of_week_step(&mut self, step: u64) {
117		self.day_of_week.add_step(step);
118	}
119
120	#[inline]
121	pub const fn add_day_of_week_range_step(&mut self, e1: u64, e2: u64, step: u64) {
122		self.day_of_week.add_range_step(e1, e2, step);
123	}
124
125	#[inline]
126	pub const fn preset_every_minute() -> Self {
127		Self::new()
128	}
129
130	#[inline]
131	pub const fn preset_every_1_minute() -> Self {
132		Self::new()
133	}
134
135	#[inline]
136	pub const fn preset_every_2_minutes() -> Self {
137		let mut c = Self::new();
138		c.add_minute_step(2);
139		c
140	}
141
142	#[inline]
143	pub const fn preset_every_even_minute() -> Self {
144		let mut c = Self::new();
145		c.add_minute_step(2);
146		c
147	}
148
149	#[inline]
150	pub const fn preset_every_uneven_minute() -> Self {
151		let mut c = Self::new();
152		c.add_minute_range_step(1, 59, 2);
153		c
154	}
155
156	#[inline]
157	pub const fn preset_every_3_minutes() -> Self {
158		let mut c = Self::new();
159		c.add_minute_step(3);
160		c
161	}
162
163	#[inline]
164	pub const fn preset_every_4_minutes() -> Self {
165		let mut c = Self::new();
166		c.add_minute_step(4);
167		c
168	}
169
170	#[inline]
171	pub const fn preset_every_5_minutes() -> Self {
172		let mut c = Self::new();
173		c.add_minute_step(5);
174		c
175	}
176
177	#[inline]
178	pub const fn preset_every_five_minutes() -> Self {
179		let mut c = Self::new();
180		c.add_minute_step(5);
181		c
182	}
183
184	#[inline]
185	pub const fn preset_every_6_minutes() -> Self {
186		let mut c = Self::new();
187		c.add_minute_step(6);
188		c
189	}
190
191	#[inline]
192	pub const fn preset_every_10_minutes() -> Self {
193		let mut c = Self::new();
194		c.add_minute_step(10);
195		c
196	}
197
198	#[inline]
199	pub const fn preset_every_15_minutes() -> Self {
200		let mut c = Self::new();
201		c.add_minute_step(15);
202		c
203	}
204
205	#[inline]
206	pub const fn preset_every_fifteen_minutes() -> Self {
207		let mut c = Self::new();
208		c.add_minute_step(15);
209		c
210	}
211
212	#[inline]
213	pub const fn preset_every_ten_minutes() -> Self {
214		let mut c = Self::new();
215		c.add_minute_step(10);
216		c
217	}
218
219	#[inline]
220	pub const fn preset_every_quarter_hour() -> Self {
221		let mut c = Self::new();
222		c.add_minute_step(15);
223		c
224	}
225
226	#[inline]
227	pub const fn preset_every_20_minutes() -> Self {
228		let mut c = Self::new();
229		c.add_minute_step(20);
230		c
231	}
232
233	#[inline]
234	pub const fn preset_every_30_minutes() -> Self {
235		let mut c = Self::new();
236		c.add_minute_step(30);
237		c
238	}
239
240	#[inline]
241	pub const fn preset_every_hour_at_30_minutes() -> Self {
242		let mut c = Self::new();
243		c.add_minute(30);
244		c
245	}
246
247	#[inline]
248	pub const fn preset_every_half_hour() -> Self {
249		let mut c = Self::new();
250		c.add_minute_step(30);
251		c
252	}
253
254	#[inline]
255	pub const fn preset_every_60_minutes() -> Self {
256		let mut c = Self::new();
257		c.add_minute(0);
258		c
259	}
260
261	#[inline]
262	pub const fn preset_every_hour() -> Self {
263		let mut c = Self::new();
264		c.add_minute(0);
265		c
266	}
267
268	#[inline]
269	pub const fn preset_every_1_hour() -> Self {
270		let mut c = Self::new();
271		c.add_minute(0);
272		c
273	}
274
275	#[inline]
276	pub const fn preset_every_2_hours() -> Self {
277		let mut c = Self::new();
278		c.add_minute(0);
279		c.add_hour_step(2);
280		c
281	}
282
283	#[inline]
284	pub const fn preset_every_two_hours() -> Self {
285		let mut c = Self::new();
286		c.add_minute(0);
287		c.add_hour_step(2);
288		c
289	}
290
291	#[inline]
292	pub const fn preset_every_even_hour() -> Self {
293		let mut c = Self::new();
294		c.add_minute(0);
295		c.add_hour_step(2);
296		c
297	}
298
299	#[inline]
300	pub const fn preset_every_other_hour() -> Self {
301		let mut c = Self::new();
302		c.add_minute(0);
303		c.add_hour_step(2);
304		c
305	}
306
307	#[inline]
308	pub const fn preset_every_3_hours() -> Self {
309		let mut c = Self::new();
310		c.add_minute(0);
311		c.add_hour_step(3);
312		c
313	}
314
315	#[inline]
316	pub const fn preset_every_three_hours() -> Self {
317		let mut c = Self::new();
318		c.add_minute(0);
319		c.add_hour_step(3);
320		c
321	}
322
323	#[inline]
324	pub const fn preset_every_4_hours() -> Self {
325		let mut c = Self::new();
326		c.add_minute(0);
327		c.add_hour_step(4);
328		c
329	}
330
331	#[inline]
332	pub const fn preset_every_6_hours() -> Self {
333		let mut c = Self::new();
334		c.add_minute(0);
335		c.add_hour_step(6);
336		c
337	}
338
339	#[inline]
340	pub const fn preset_every_six_hours() -> Self {
341		let mut c = Self::new();
342		c.add_minute(0);
343		c.add_hour_step(6);
344		c
345	}
346
347	#[inline]
348	pub const fn preset_every_8_hours() -> Self {
349		let mut c = Self::new();
350		c.add_minute(0);
351		c.add_hour_step(8);
352		c
353	}
354
355	#[inline]
356	pub const fn preset_every_12_hours() -> Self {
357		let mut c = Self::new();
358		c.add_minute(0);
359		c.add_hour_step(12);
360		c
361	}
362
363	#[inline]
364	pub const fn preset_hour_range(start: u64, end: u64) -> Self {
365		let mut c = Self::new();
366		c.add_minute(0);
367		c.add_hour_range(start, end);
368		c
369	}
370
371	#[inline]
372	pub const fn preset_between_certain_hours(start: u64, end: u64) -> Self {
373		let mut c = Self::new();
374		c.add_minute(0);
375		c.add_hour_range(start, end);
376		c
377	}
378
379	#[inline]
380	pub const fn preset_every_day() -> Self {
381		let mut c = Self::new();
382		c.add_minute(0);
383		c.add_hour(0);
384		c
385	}
386
387	#[inline]
388	pub const fn preset_daily() -> Self {
389		let mut c = Self::new();
390		c.add_minute(0);
391		c.add_hour(0);
392		c
393	}
394
395	#[inline]
396	pub const fn preset_once_a_day() -> Self {
397		let mut c = Self::new();
398		c.add_minute(0);
399		c.add_hour(0);
400		c
401	}
402
403	#[inline]
404	pub const fn preset_every_night() -> Self {
405		let mut c = Self::new();
406		c.add_minute(0);
407		c.add_hour(0);
408		c
409	}
410
411	#[inline]
412	pub const fn preset_every_day_at_0100() -> Self {
413		let mut c = Self::new();
414		c.add_minute(0);
415		c.add_hour(1);
416		c
417	}
418
419	#[inline]
420	pub const fn preset_every_day_at_0200() -> Self {
421		let mut c = Self::new();
422		c.add_minute(0);
423		c.add_hour(2);
424		c
425	}
426
427	#[inline]
428	pub const fn preset_every_day_at_0800() -> Self {
429		let mut c = Self::new();
430		c.add_minute(0);
431		c.add_hour(8);
432		c
433	}
434
435	#[inline]
436	pub const fn preset_every_morning() -> Self {
437		let mut c = Self::new();
438		c.add_minute(0);
439		c.add_hour(9);
440		c
441	}
442
443	#[inline]
444	pub const fn preset_every_midnight() -> Self {
445		let mut c = Self::new();
446		c.add_minute(0);
447		c.add_hour(0);
448		c
449	}
450
451	#[inline]
452	pub const fn preset_every_day_at_midnight() -> Self {
453		let mut c = Self::new();
454		c.add_minute(0);
455		c.add_hour(0);
456		c
457	}
458
459	#[inline]
460	pub const fn preset_every_night_at_midnight() -> Self {
461		let mut c = Self::new();
462		c.add_minute(0);
463		c.add_hour(0);
464		c
465	}
466
467	#[inline]
468	pub const fn preset_every_sunday() -> Self {
469		let mut c = Self::new();
470		c.add_minute(0);
471		c.add_hour(0);
472		c.add_day_of_week(DayOfWeek::SUN);
473		c
474	}
475
476	#[inline]
477	pub const fn preset_every_monday() -> Self {
478		let mut c = Self::new();
479		c.add_minute(0);
480		c.add_hour(0);
481		c.add_day_of_week(DayOfWeek::MON);
482		c
483	}
484
485	#[inline]
486	pub const fn preset_every_tuesday() -> Self {
487		let mut c = Self::new();
488		c.add_minute(0);
489		c.add_hour(0);
490		c.add_day_of_week(DayOfWeek::TUE);
491		c
492	}
493
494	#[inline]
495	pub const fn preset_every_wednesday() -> Self {
496		let mut c = Self::new();
497		c.add_minute(0);
498		c.add_hour(0);
499		c.add_day_of_week(DayOfWeek::WED);
500		c
501	}
502
503	#[inline]
504	pub const fn preset_every_thursday() -> Self {
505		let mut c = Self::new();
506		c.add_minute(0);
507		c.add_hour(0);
508		c.add_day_of_week(DayOfWeek::THU);
509		c
510	}
511
512	#[inline]
513	pub const fn preset_every_friday() -> Self {
514		let mut c = Self::new();
515		c.add_minute(0);
516		c.add_hour(0);
517		c.add_day_of_week(DayOfWeek::FRI);
518		c
519	}
520
521	#[inline]
522	pub const fn preset_every_friday_at_midnight() -> Self {
523		let mut c = Self::new();
524		c.add_minute(0);
525		c.add_hour(0);
526		c.add_day_of_week(DayOfWeek::FRI);
527		c
528	}
529
530	#[inline]
531	pub const fn preset_every_saturday() -> Self {
532		let mut c = Self::new();
533		c.add_minute(0);
534		c.add_hour(0);
535		c.add_day_of_week(DayOfWeek::SAT);
536		c
537	}
538
539	#[inline]
540	pub const fn preset_every_weekday() -> Self {
541		let mut c = Self::new();
542		c.add_minute(0);
543		c.add_hour(0);
544		c.add_day_of_week_range(DayOfWeek::MON, DayOfWeek::FRI);
545		c
546	}
547
548	#[inline]
549	pub const fn preset_weekdays_only() -> Self {
550		let mut c = Self::new();
551		c.add_minute(0);
552		c.add_hour(0);
553		c.add_day_of_week_range(DayOfWeek::MON, DayOfWeek::FRI);
554		c
555	}
556
557	#[inline]
558	pub const fn preset_monday_to_friday() -> Self {
559		let mut c = Self::new();
560		c.add_minute(0);
561		c.add_hour(0);
562		c.add_day_of_week_range(DayOfWeek::MON, DayOfWeek::FRI);
563		c
564	}
565
566	#[inline]
567	pub const fn preset_every_weekend() -> Self {
568		let mut c = Self::new();
569		c.add_minute(0);
570		c.add_hour(0);
571		c.add_day_of_week(DayOfWeek::SAT);
572		c.add_day_of_week(DayOfWeek::SUN);
573		c
574	}
575
576	#[inline]
577	pub const fn preset_weekends_only() -> Self {
578		let mut c = Self::new();
579		c.add_minute(0);
580		c.add_hour(0);
581		c.add_day_of_week(DayOfWeek::SAT);
582		c.add_day_of_week(DayOfWeek::SUN);
583		c
584	}
585
586	#[inline]
587	pub const fn preset_every_7_days() -> Self {
588		let mut c = Self::new();
589		c.add_minute(0);
590		c.add_hour(0);
591		c.add_day_of_week(DayOfWeek::SUN);
592		c
593	}
594
595	#[inline]
596	pub const fn preset_every_week() -> Self {
597		let mut c = Self::new();
598		c.add_minute(0);
599		c.add_hour(0);
600		c.add_day_of_week(DayOfWeek::SUN);
601		c
602	}
603
604	#[inline]
605	pub const fn preset_weekly() -> Self {
606		let mut c = Self::new();
607		c.add_minute(0);
608		c.add_hour(0);
609		c.add_day_of_week(DayOfWeek::SUN);
610		c
611	}
612
613	#[inline]
614	pub const fn preset_once_a_week() -> Self {
615		let mut c = Self::new();
616		c.add_minute(0);
617		c.add_hour(0);
618		c.add_day_of_week(DayOfWeek::SUN);
619		c
620	}
621
622	#[inline]
623	pub const fn preset_every_month() -> Self {
624		let mut c = Self::new();
625		c.add_minute(0);
626		c.add_hour(0);
627		c.add_day_of_month(1);
628		c
629	}
630
631	#[inline]
632	pub const fn preset_monthly() -> Self {
633		let mut c = Self::new();
634		c.add_minute(0);
635		c.add_hour(0);
636		c.add_day_of_month(1);
637		c
638	}
639
640	#[inline]
641	pub const fn preset_once_a_month() -> Self {
642		let mut c = Self::new();
643		c.add_minute(0);
644		c.add_hour(0);
645		c.add_day_of_month(1);
646		c
647	}
648
649	#[inline]
650	pub const fn preset_every_other_month() -> Self {
651		let mut c = Self::new();
652		c.add_minute(0);
653		c.add_hour(0);
654		c.add_day_of_month(1);
655		c.add_month_step(2);
656		c
657	}
658
659	#[inline]
660	pub const fn preset_every_quarter() -> Self {
661		let mut c = Self::new();
662		c.add_minute(0);
663		c.add_hour(0);
664		c.add_day_of_month(1);
665		c.add_month_step(3);
666		c
667	}
668
669	#[inline]
670	pub const fn preset_every_6_months() -> Self {
671		let mut c = Self::new();
672		c.add_minute(0);
673		c.add_hour(0);
674		c.add_day_of_month(1);
675		c.add_month_step(6);
676		c
677	}
678
679	#[inline]
680	pub const fn preset_every_year() -> Self {
681		let mut c = Self::new();
682		c.add_minute(0);
683		c.add_hour(0);
684		c.add_day_of_month(1);
685		c.add_month(1);
686		c
687	}
688}
689
690impl Default for CronSchedule {
691	#[inline]
692	fn default() -> Self {
693		Self::new()
694	}
695}
696
697#[derive(Clone, Copy)]
698pub struct Minute {
699	inner: u64
700}
701
702impl Minute {
703	pub const MIN: u64 = 0;
704	pub const MAX: u64 = 59;
705
706	#[inline]
707	const fn new() -> Self {
708		Self { inner: 0 }
709	}
710
711	#[inline]
712	const fn check_range(minute: u64) -> bool {
713		minute <= 59
714	}
715
716	#[inline]
717	const fn add(&mut self, minute: u64) {
718		if !self.add_checked(minute) {
719			panic!("provided `minute` out of range")
720		}
721	}
722
723	#[inline]
724	const fn add_checked(&mut self, minute: u64) -> bool {
725		if !Self::check_range(minute) { return false }
726
727		// SAFETY: just checked `minute` is in range
728		unsafe { self.add_unchecked(minute) }
729		true
730	}
731
732	#[inline]
733	const unsafe fn add_unchecked(&mut self, minute: u64) {
734		// SAFETY: safety precondition upheld by caller
735		unsafe { hint::assert_unchecked(Self::check_range(minute)) }
736
737		self.inner |= 1 << minute;
738	}
739
740	#[inline]
741	const fn add_range(&mut self, e1: u64, e2: u64) {
742		if !self.add_range_checked(e1, e2) {
743			panic!("provided `e1` and/or `e2` out of range")
744		}
745	}
746
747	#[inline]
748	const fn add_range_checked(&mut self, e1: u64, e2: u64) -> bool {
749		if !Self::check_range(e1) { return false }
750		if !Self::check_range(e2) { return false }
751
752		// SAFETY: just checked `e1` and `e2` are in range
753		unsafe { self.add_range_unchecked(e1, e2) }
754		true
755	}
756
757	#[inline]
758	const unsafe fn add_range_unchecked(&mut self, e1: u64, e2: u64) {
759		// SAFETY: safety precondition upheld by caller
760		unsafe { self.add_range_step_unchecked(e1, e2, 1) }
761	}
762
763	#[inline]
764	const fn add_step(&mut self, step: u64) {
765		// SAFETY: safety precondition upheld by caller
766		// `MIN` and `MAX` are within range too
767		unsafe { self.add_range_step_unchecked(Self::MIN, Self::MAX, step) }
768	}
769
770	#[inline]
771	const fn add_range_step(&mut self, e1: u64, e2: u64, step: u64) {
772		if !self.add_range_step_checked(e1, e2, step) {
773			panic!("provided `e1` and/or `e2` out of range")
774		}
775	}
776
777	#[inline]
778	const fn add_range_step_checked(&mut self, e1: u64, e2: u64, step: u64) -> bool {
779		if !Self::check_range(e1) { return false }
780		if !Self::check_range(e2) { return false }
781
782		// SAFETY: just checked `e1` and `e2` are in range
783		unsafe { self.add_range_step_unchecked(e1, e2, step) }
784		true
785	}
786
787	#[inline]
788	const unsafe fn add_range_step_unchecked(&mut self, mut e1: u64, e2: u64, step: u64) {
789		// SAFETY: safety precondition upheld by caller
790		unsafe { hint::assert_unchecked(Self::check_range(e1)) }
791		// SAFETY: same as above
792		unsafe { hint::assert_unchecked(Self::check_range(e2)) }
793		// SAFETY: same as above
794		unsafe { hint::assert_unchecked(e1 <= e2) }
795
796		while e1 <= e2 {
797			// SAFETY: safety precondition upheld by caller
798			// and checked by if statement
799			unsafe { self.add_unchecked(e1) }
800
801			e1 += step;
802		}
803	}
804
805	// #[inline]
806	// const fn union(&mut self, other: Self) {
807	// 	self.inner |= other.inner;
808	// }
809
810	// #[inline]
811	// const fn intersection(&mut self, other: Self) {
812	// 	self.inner &= other.inner;
813	// }
814}
815
816#[derive(Clone, Copy)]
817pub struct Hour {
818	inner: u32
819}
820
821impl Hour {
822	pub const MIN: u64 = 0;
823	pub const MAX: u64 = 23;
824
825	#[inline]
826	const fn new() -> Self {
827		Self { inner: 0 }
828	}
829
830	#[inline]
831	const fn check_range(hour: u64) -> bool {
832		hour <= 23
833	}
834
835	#[inline]
836	const fn add(&mut self, hour: u64) {
837		if !self.add_checked(hour) {
838			panic!("provided `hour` out of range")
839		}
840	}
841
842	#[inline]
843	const fn add_checked(&mut self, hour: u64) -> bool {
844		if !Self::check_range(hour) { return false }
845
846		// SAFETY: just checked `hour` is in range
847		unsafe { self.add_unchecked(hour) }
848		true
849	}
850
851	#[inline]
852	const unsafe fn add_unchecked(&mut self, hour: u64) {
853		// SAFETY: safety precondition upheld by caller
854		unsafe { hint::assert_unchecked(Self::check_range(hour)) }
855
856		self.inner |= 1 << hour;
857	}
858
859	#[inline]
860	const fn add_range(&mut self, e1: u64, e2: u64) {
861		if !self.add_range_checked(e1, e2) {
862			panic!("provided `e1` and/or `e2` out of range")
863		}
864	}
865
866	#[inline]
867	const fn add_range_checked(&mut self, e1: u64, e2: u64) -> bool {
868		if !Self::check_range(e1) { return false }
869		if !Self::check_range(e2) { return false }
870
871		// SAFETY: just checked `e1` and `e2` are in range
872		unsafe { self.add_range_unchecked(e1, e2) }
873		true
874	}
875
876	#[inline]
877	const unsafe fn add_range_unchecked(&mut self, e1: u64, e2: u64) {
878		// SAFETY: safety precondition upheld by caller
879		unsafe { self.add_range_step_unchecked(e1, e2, 1) }
880	}
881
882	#[inline]
883	const fn add_step(&mut self, step: u64) {
884		// SAFETY: safety precondition upheld by caller
885		// `MIN` and `MAX` are within range too
886		unsafe { self.add_range_step_unchecked(Self::MIN, Self::MAX, step) }
887	}
888
889	#[inline]
890	const fn add_range_step(&mut self, e1: u64, e2: u64, step: u64) {
891		if !self.add_range_step_checked(e1, e2, step) {
892			panic!("provided `e1` and/or `e2` out of range")
893		}
894	}
895
896	#[inline]
897	const fn add_range_step_checked(&mut self, e1: u64, e2: u64, step: u64) -> bool {
898		if !Self::check_range(e1) { return false }
899		if !Self::check_range(e2) { return false }
900
901		// SAFETY: just checked `e1` and `e2` are in range
902		unsafe { self.add_range_step_unchecked(e1, e2, step) }
903		true
904	}
905
906	#[inline]
907	const unsafe fn add_range_step_unchecked(&mut self, mut e1: u64, e2: u64, step: u64) {
908		// SAFETY: safety precondition upheld by caller
909		unsafe { hint::assert_unchecked(Self::check_range(e1)) }
910		// SAFETY: same as above
911		unsafe { hint::assert_unchecked(Self::check_range(e2)) }
912		// SAFETY: same as above
913		unsafe { hint::assert_unchecked(e1 <= e2) }
914
915		while e1 <= e2 {
916			// SAFETY: safety precondition upheld by caller
917			// and checked by if statement
918			unsafe { self.add_unchecked(e1) }
919
920			e1 += step;
921		}
922	}
923
924	// #[inline]
925	// const fn union(&mut self, other: Self) {
926	// 	self.inner |= other.inner;
927	// }
928
929	// #[inline]
930	// const fn intersection(&mut self, other: Self) {
931	// 	self.inner &= other.inner;
932	// }
933}
934
935#[derive(Clone, Copy)]
936pub struct DayOfMonth {
937	inner: u32
938}
939
940impl DayOfMonth {
941	pub const MIN: u64 = 1;
942	pub const MAX: u64 = 31;
943
944	#[inline]
945	const fn new() -> Self {
946		Self { inner: 0 }
947	}
948
949	#[inline]
950	const fn check_range(day_of_month: u64) -> bool {
951		day_of_month >= 1 && day_of_month <= 31
952	}
953
954	#[inline]
955	const fn add(&mut self, day_of_month: u64) {
956		if !self.add_checked(day_of_month) {
957			panic!("provided `day_of_month` out of range")
958		}
959	}
960
961	#[inline]
962	const fn add_checked(&mut self, day_of_month: u64) -> bool {
963		if !Self::check_range(day_of_month) { return false }
964
965		// SAFETY: just checked `day_of_month` is in range
966		unsafe { self.add_unchecked(day_of_month) }
967		true
968	}
969
970	#[inline]
971	const unsafe fn add_unchecked(&mut self, day_of_month: u64) {
972		// SAFETY: safety precondition upheld by caller
973		unsafe { hint::assert_unchecked(Self::check_range(day_of_month)) }
974
975		self.inner |= 1 << (day_of_month - 1);
976	}
977
978	#[inline]
979	const fn add_range(&mut self, e1: u64, e2: u64) {
980		if !self.add_range_checked(e1, e2) {
981			panic!("provided `e1` and/or `e2` out of range")
982		}
983	}
984
985	#[inline]
986	const fn add_range_checked(&mut self, e1: u64, e2: u64) -> bool {
987		if !Self::check_range(e1) { return false }
988		if !Self::check_range(e2) { return false }
989
990		// SAFETY: just checked `e1` and `e2` are in range
991		unsafe { self.add_range_unchecked(e1, e2) }
992		true
993	}
994
995	#[inline]
996	const unsafe fn add_range_unchecked(&mut self, e1: u64, e2: u64) {
997		// SAFETY: safety precondition upheld by caller
998		unsafe { self.add_range_step_unchecked(e1, e2, 1) }
999	}
1000
1001	#[inline]
1002	const fn add_step(&mut self, step: u64) {
1003		// SAFETY: safety precondition upheld by caller
1004		// `MIN` and `MAX` are within range too
1005		unsafe { self.add_range_step_unchecked(Self::MIN, Self::MAX, step) }
1006	}
1007
1008	#[inline]
1009	const fn add_range_step(&mut self, e1: u64, e2: u64, step: u64) {
1010		if !self.add_range_step_checked(e1, e2, step) {
1011			panic!("provided `e1` and/or `e2` out of range")
1012		}
1013	}
1014
1015	#[inline]
1016	const fn add_range_step_checked(&mut self, e1: u64, e2: u64, step: u64) -> bool {
1017		if !Self::check_range(e1) { return false }
1018		if !Self::check_range(e2) { return false }
1019
1020		// SAFETY: just checked `e1` and `e2` are in range
1021		unsafe { self.add_range_step_unchecked(e1, e2, step) }
1022		true
1023	}
1024
1025	#[inline]
1026	const unsafe fn add_range_step_unchecked(&mut self, mut e1: u64, e2: u64, step: u64) {
1027		// SAFETY: safety precondition upheld by caller
1028		unsafe { hint::assert_unchecked(Self::check_range(e1)) }
1029		// SAFETY: same as above
1030		unsafe { hint::assert_unchecked(Self::check_range(e2)) }
1031		// SAFETY: same as above
1032		unsafe { hint::assert_unchecked(e1 <= e2) }
1033
1034		while e1 <= e2 {
1035			// SAFETY: safety precondition upheld by caller
1036			// and checked by if statement
1037			unsafe { self.add_unchecked(e1) }
1038
1039			e1 += step;
1040		}
1041	}
1042
1043	// #[inline]
1044	// const fn union(&mut self, other: Self) {
1045	// 	self.inner |= other.inner;
1046	// }
1047
1048	// #[inline]
1049	// const fn intersection(&mut self, other: Self) {
1050	// 	self.inner &= other.inner;
1051	// }
1052}
1053
1054#[derive(Clone, Copy)]
1055pub struct Month {
1056	inner: u16
1057}
1058
1059impl Month {
1060	pub const MIN: u64 = 1;
1061	pub const MAX: u64 = 12;
1062
1063	pub const JANUARY: u64 = 1;
1064	pub const FEBRUARY: u64 = 2;
1065	pub const MARCH: u64 = 3;
1066	pub const APRIL: u64 = 4;
1067	pub const MAY: u64 = 5;
1068	pub const JUNE: u64 = 6;
1069	pub const JULY: u64 = 7;
1070	pub const AUGUST: u64 = 8;
1071	pub const SEPTEMBER: u64 = 9;
1072	pub const OCTOBER: u64 = 10;
1073	pub const NOVEMBER: u64 = 11;
1074	pub const DECEMBER: u64 = 12;
1075
1076	pub const JAN: u64 = Self::JANUARY;
1077	pub const FEB: u64 = Self::FEBRUARY;
1078	pub const MAR: u64 = Self::MARCH;
1079	pub const APR: u64 = Self::APRIL;
1080	// le may is already 3 letter
1081	pub const JUN: u64 = Self::JUNE;
1082	pub const JUL: u64 = Self::JULY;
1083	pub const AUG: u64 = Self::AUGUST;
1084	pub const SEP: u64 = Self::SEPTEMBER;
1085	pub const OCT: u64 = Self::OCTOBER;
1086	pub const NOV: u64 = Self::NOVEMBER;
1087	pub const DEC: u64 = Self::DECEMBER;
1088
1089	#[inline]
1090	const fn new() -> Self {
1091		Self { inner: 0 }
1092	}
1093
1094	#[inline]
1095	const fn check_range(month: u64) -> bool {
1096		month >= 1 && month <= 12
1097	}
1098
1099	#[inline]
1100	const fn add(&mut self, month: u64) {
1101		if !self.add_checked(month) {
1102			panic!("provided `month` out of range")
1103		}
1104	}
1105
1106	#[inline]
1107	const fn add_checked(&mut self, month: u64) -> bool {
1108		if !Self::check_range(month) { return false }
1109
1110		// SAFETY: just checked `month` is in range
1111		unsafe { self.add_unchecked(month) }
1112		true
1113	}
1114
1115	#[inline]
1116	const unsafe fn add_unchecked(&mut self, month: u64) {
1117		// SAFETY: safety precondition upheld by caller
1118		unsafe { hint::assert_unchecked(Self::check_range(month)) }
1119
1120		self.inner |= 1 << (month - 1);
1121	}
1122
1123	#[inline]
1124	const fn add_range(&mut self, e1: u64, e2: u64) {
1125		if !self.add_range_checked(e1, e2) {
1126			panic!("provided `e1` and/or `e2` out of range")
1127		}
1128	}
1129
1130	#[inline]
1131	const fn add_range_checked(&mut self, e1: u64, e2: u64) -> bool {
1132		if !Self::check_range(e1) { return false }
1133		if !Self::check_range(e2) { return false }
1134
1135		// SAFETY: just checked `e1` and `e2` are in range
1136		unsafe { self.add_range_unchecked(e1, e2) }
1137		true
1138	}
1139
1140	#[inline]
1141	const unsafe fn add_range_unchecked(&mut self, e1: u64, e2: u64) {
1142		// SAFETY: safety precondition upheld by caller
1143		unsafe { self.add_range_step_unchecked(e1, e2, 1) }
1144	}
1145
1146	#[inline]
1147	const fn add_step(&mut self, step: u64) {
1148		// SAFETY: safety precondition upheld by caller
1149		// `MIN` and `MAX` are within range too
1150		unsafe { self.add_range_step_unchecked(Self::MIN, Self::MAX, step) }
1151	}
1152
1153	#[inline]
1154	const fn add_range_step(&mut self, e1: u64, e2: u64, step: u64) {
1155		if !self.add_range_step_checked(e1, e2, step) {
1156			panic!("provided `e1` and/or `e2` out of range")
1157		}
1158	}
1159
1160	#[inline]
1161	const fn add_range_step_checked(&mut self, e1: u64, e2: u64, step: u64) -> bool {
1162		if !Self::check_range(e1) { return false }
1163		if !Self::check_range(e2) { return false }
1164
1165		// SAFETY: just checked `e1` and `e2` are in range
1166		unsafe { self.add_range_step_unchecked(e1, e2, step) }
1167		true
1168	}
1169
1170	#[inline]
1171	const unsafe fn add_range_step_unchecked(&mut self, mut e1: u64, e2: u64, step: u64) {
1172		// SAFETY: safety precondition upheld by caller
1173		unsafe { hint::assert_unchecked(Self::check_range(e1)) }
1174		// SAFETY: same as above
1175		unsafe { hint::assert_unchecked(Self::check_range(e2)) }
1176		// SAFETY: same as above
1177		unsafe { hint::assert_unchecked(e1 <= e2) }
1178
1179		while e1 <= e2 {
1180			// SAFETY: safety precondition upheld by caller
1181			// and checked by if statement
1182			unsafe { self.add_unchecked(e1) }
1183
1184			e1 += step;
1185		}
1186	}
1187
1188	// #[inline]
1189	// const fn union(&mut self, other: Self) {
1190	// 	self.inner |= other.inner;
1191	// }
1192
1193	// #[inline]
1194	// const fn intersection(&mut self, other: Self) {
1195	// 	self.inner &= other.inner;
1196	// }
1197}
1198
1199#[derive(Clone, Copy)]
1200pub struct DayOfWeek {
1201	inner: u8
1202}
1203
1204impl DayOfWeek {
1205	pub const MIN: u64 = 0;
1206	pub const MAX: u64 = 6;
1207
1208	pub const SUNDAY: u64 = 0;
1209	pub const MONDAY: u64 = 1;
1210	pub const TUESDAY: u64 = 2;
1211	pub const WEDNESDAY: u64 = 3;
1212	pub const THURSDAY: u64 = 4;
1213	pub const FRIDAY: u64 = 5;
1214	pub const SATURDAY: u64 = 6;
1215
1216	pub const SUN: u64 = Self::SUNDAY;
1217	pub const MON: u64 = Self::MONDAY;
1218	pub const TUE: u64 = Self::TUESDAY;
1219	pub const WED: u64 = Self::WEDNESDAY;
1220	pub const THU: u64 = Self::THURSDAY;
1221	pub const FRI: u64 = Self::FRIDAY;
1222	pub const SAT: u64 = Self::SATURDAY;
1223
1224	#[inline]
1225	const fn new() -> Self {
1226		Self { inner: 0 }
1227	}
1228
1229	#[inline]
1230	const fn check_range(day_of_week: u64) -> bool {
1231		day_of_week <= 6
1232	}
1233
1234	#[inline]
1235	const fn add(&mut self, day_of_week: u64) {
1236		if !self.add_checked(day_of_week) {
1237			panic!("provided `day_of_week` out of range")
1238		}
1239	}
1240
1241	#[inline]
1242	const fn add_checked(&mut self, day_of_week: u64) -> bool {
1243		if !Self::check_range(day_of_week) { return false }
1244
1245		// SAFETY: just checked `day_of_week` is in range
1246		unsafe { self.add_unchecked(day_of_week) }
1247		true
1248	}
1249
1250	#[inline]
1251	const unsafe fn add_unchecked(&mut self, day_of_week: u64) {
1252		// SAFETY: safety precondition upheld by caller
1253		unsafe { hint::assert_unchecked(Self::check_range(day_of_week)) }
1254
1255		self.inner |= 1 << day_of_week;
1256	}
1257
1258	#[inline]
1259	const fn add_range(&mut self, e1: u64, e2: u64) {
1260		if !self.add_range_checked(e1, e2) {
1261			panic!("provided `e1` and/or `e2` out of range")
1262		}
1263	}
1264
1265	#[inline]
1266	const fn add_range_checked(&mut self, e1: u64, e2: u64) -> bool {
1267		if !Self::check_range(e1) { return false }
1268		if !Self::check_range(e2) { return false }
1269
1270		// SAFETY: just checked `e1` and `e2` are in range
1271		unsafe { self.add_range_unchecked(e1, e2) }
1272		true
1273	}
1274
1275	#[inline]
1276	const unsafe fn add_range_unchecked(&mut self, e1: u64, e2: u64) {
1277		// SAFETY: safety precondition upheld by caller
1278		unsafe { self.add_range_step_unchecked(e1, e2, 1) }
1279	}
1280
1281	#[inline]
1282	const fn add_step(&mut self, step: u64) {
1283		// SAFETY: safety precondition upheld by caller
1284		// `MIN` and `MAX` are within range too
1285		unsafe { self.add_range_step_unchecked(Self::MIN, Self::MAX, step) }
1286	}
1287
1288	#[inline]
1289	const fn add_range_step(&mut self, e1: u64, e2: u64, step: u64) {
1290		if !self.add_range_step_checked(e1, e2, step) {
1291			panic!("provided `e1` and/or `e2` out of range")
1292		}
1293	}
1294
1295	#[inline]
1296	const fn add_range_step_checked(&mut self, e1: u64, e2: u64, step: u64) -> bool {
1297		if !Self::check_range(e1) { return false }
1298		if !Self::check_range(e2) { return false }
1299
1300		// SAFETY: just checked `e1` and `e2` are in range
1301		unsafe { self.add_range_step_unchecked(e1, e2, step) }
1302		true
1303	}
1304
1305	#[inline]
1306	const unsafe fn add_range_step_unchecked(&mut self, mut e1: u64, e2: u64, step: u64) {
1307		// SAFETY: safety precondition upheld by caller
1308		unsafe { hint::assert_unchecked(Self::check_range(e1)) }
1309		// SAFETY: same as above
1310		unsafe { hint::assert_unchecked(Self::check_range(e2)) }
1311		// SAFETY: same as above
1312		unsafe { hint::assert_unchecked(e1 <= e2) }
1313
1314		while e1 <= e2 {
1315			// SAFETY: safety precondition upheld by caller
1316			// and checked by if statement
1317			unsafe { self.add_unchecked(e1) }
1318
1319			e1 += step;
1320		}
1321	}
1322
1323	// #[inline]
1324	// const fn union(&mut self, other: Self) {
1325	// 	self.inner |= other.inner;
1326	// }
1327
1328	// #[inline]
1329	// const fn intersection(&mut self, other: Self) {
1330	// 	self.inner &= other.inner;
1331	// }
1332}