jiff/civil/weekday.rs
1use crate::error::Error;
2
3/// A representation for the day of the week.
4///
5/// The default representation follows ISO 8601. That is, the week starts with
6/// Monday and numbering starts at `1`. However, the various constructors and
7/// accessors support using other schemes in wide use:
8///
9/// * [`Weekday::from_monday_zero_offset`] builds a weekday from
10/// a scheme that starts the week on Monday at offset `0`, while
11/// [`Weekday::to_monday_zero_offset`] converts to it.
12/// * [`Weekday::from_monday_one_offset`] builds a weekday from a scheme
13/// that starts the week on Monday at offset `1` (the default representation),
14/// while [`Weekday::to_monday_one_offset`] converts to it.
15/// * [`Weekday::from_sunday_zero_offset`] builds a weekday from
16/// a scheme that starts the week on Sunday at offset `0`, while
17/// [`Weekday::to_sunday_zero_offset`] converts to it.
18/// * [`Weekday::from_sunday_one_offset`] builds a weekday from
19/// a scheme that starts the week on Sunday at offset `1`, while
20/// [`Weekday::to_sunday_one_offset`] converts to it.
21///
22/// # Arithmetic
23///
24/// This type provides [`Weekday::wrapping_add`] and [`Weekday::wrapping_sub`]
25/// for performing wrapping arithmetic on weekdays. These are also available
26/// via operator overloading:
27///
28/// ```
29/// use jiff::civil::Weekday;
30///
31/// assert_eq!(Weekday::Monday + 1, Weekday::Tuesday);
32/// assert_eq!(Weekday::Sunday - 1, Weekday::Saturday);
33/// ```
34///
35/// # Comparisons
36///
37/// This type provides `Eq` and `PartialEq` trait implementations for easy
38/// comparison:
39///
40/// ```
41/// use jiff::civil::Weekday;
42///
43/// assert_eq!(Weekday::Wednesday, Weekday::Wednesday + 7);
44/// assert_ne!(Weekday::Thursday, Weekday::Friday);
45/// ```
46///
47/// But this type specifically does not provide `Ord` or `PartialOrd` trait
48/// implementations. Such an implementation would require deciding whether
49/// Sunday is less than Monday or greater than Monday. The former case
50/// corresponds to a week scheme where Sunday is the first day in the week,
51/// where as the latter corresponds to a scheme where Monday is the first day.
52/// Since both schemes are in widespread use, it would be inappropriate to bake
53/// in an assumption of one or the other. Instead, one can convert a weekday
54/// into the desired offset scheme, and then compare the offsets:
55///
56/// ```
57/// use jiff::civil::Weekday;
58///
59/// let (sun, mon) = (Weekday::Sunday, Weekday::Monday);
60/// assert!(sun.to_sunday_zero_offset() < mon.to_sunday_zero_offset());
61/// assert!(sun.to_monday_zero_offset() > mon.to_monday_zero_offset());
62/// ```
63///
64/// # Example
65///
66/// This example shows the result of converting to and from different schemes:
67///
68/// ```
69/// use jiff::civil::Weekday;
70///
71/// // The different representations of Monday.
72/// assert_eq!(Weekday::Monday.to_monday_zero_offset(), 0);
73/// assert_eq!(Weekday::Monday.to_monday_one_offset(), 1);
74/// assert_eq!(Weekday::Monday.to_sunday_zero_offset(), 1);
75/// assert_eq!(Weekday::Monday.to_sunday_one_offset(), 2);
76///
77/// // The different representations of Sunday.
78/// assert_eq!(Weekday::Sunday.to_monday_zero_offset(), 6);
79/// assert_eq!(Weekday::Sunday.to_monday_one_offset(), 7);
80/// assert_eq!(Weekday::Sunday.to_sunday_zero_offset(), 0);
81/// assert_eq!(Weekday::Sunday.to_sunday_one_offset(), 1);
82/// ```
83#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
84#[cfg_attr(feature = "defmt", derive(defmt::Format))]
85#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
86#[repr(u8)]
87#[allow(missing_docs)]
88pub enum Weekday {
89 Monday = 1,
90 Tuesday = 2,
91 Wednesday = 3,
92 Thursday = 4,
93 Friday = 5,
94 Saturday = 6,
95 Sunday = 7,
96}
97
98impl Weekday {
99 /// Convert an offset to a structured `Weekday`.
100 ///
101 /// The offset should be from a scheme where the first day of the week
102 /// is Monday and starts numbering at `0`.
103 ///
104 /// # Errors
105 ///
106 /// This returns an error when the given offset is not in the range
107 /// `0..=6`.
108 ///
109 /// # Example
110 ///
111 /// ```
112 /// use jiff::civil::Weekday;
113 ///
114 /// let weekday = Weekday::from_monday_zero_offset(3)?;
115 /// assert_eq!(weekday, Weekday::Thursday);
116 ///
117 /// assert!(Weekday::from_monday_zero_offset(7).is_err());
118 /// assert!(Weekday::from_monday_zero_offset(-1).is_err());
119 ///
120 /// # Ok::<(), Box<dyn std::error::Error>>(())
121 /// ```
122 #[inline]
123 pub fn from_monday_zero_offset(offset: i8) -> Result<Weekday, Error> {
124 jcore::civil::Weekday::from_monday_zero_offset(offset)
125 .map_err(Error::jcore_range)
126 .map(Weekday::from_jcore)
127 }
128
129 /// Convert an offset to a structured `Weekday`.
130 ///
131 /// The offset should be from a scheme where the first day of the week
132 /// is Monday and starts numbering at `1`.
133 ///
134 /// # Errors
135 ///
136 /// This returns an error when the given offset is not in the range
137 /// `1..=7`.
138 ///
139 /// # Example
140 ///
141 /// ```
142 /// use jiff::civil::Weekday;
143 ///
144 /// let weekday = Weekday::from_monday_one_offset(4)?;
145 /// assert_eq!(weekday, Weekday::Thursday);
146 ///
147 /// assert!(Weekday::from_monday_one_offset(8).is_err());
148 /// assert!(Weekday::from_monday_one_offset(0).is_err());
149 ///
150 /// # Ok::<(), Box<dyn std::error::Error>>(())
151 /// ```
152 #[inline]
153 pub fn from_monday_one_offset(offset: i8) -> Result<Weekday, Error> {
154 jcore::civil::Weekday::from_monday_one_offset(offset)
155 .map_err(Error::jcore_range)
156 .map(Weekday::from_jcore)
157 }
158
159 /// Convert an offset to a structured `Weekday`.
160 ///
161 /// The offset should be from a scheme where the first day of the week
162 /// is Sunday and starts numbering at `0`.
163 ///
164 /// # Errors
165 ///
166 /// This returns an error when the given offset is not in the range
167 /// `0..=6`.
168 ///
169 /// # Example
170 ///
171 /// ```
172 /// use jiff::civil::Weekday;
173 ///
174 /// let weekday = Weekday::from_sunday_zero_offset(0)?;
175 /// assert_eq!(weekday, Weekday::Sunday);
176 /// let weekday = Weekday::from_sunday_zero_offset(4)?;
177 /// assert_eq!(weekday, Weekday::Thursday);
178 ///
179 /// assert!(Weekday::from_sunday_zero_offset(7).is_err());
180 /// assert!(Weekday::from_sunday_zero_offset(-1).is_err());
181 ///
182 /// # Ok::<(), Box<dyn std::error::Error>>(())
183 /// ```
184 #[inline]
185 pub fn from_sunday_zero_offset(offset: i8) -> Result<Weekday, Error> {
186 jcore::civil::Weekday::from_sunday_zero_offset(offset)
187 .map_err(Error::jcore_range)
188 .map(Weekday::from_jcore)
189 }
190
191 /// Convert an offset to a structured `Weekday`.
192 ///
193 /// The offset should be from a scheme where the first day of the week
194 /// is Sunday and starts numbering at `1`.
195 ///
196 /// # Errors
197 ///
198 /// This returns an error when the given offset is not in the range
199 /// `1..=7`.
200 ///
201 /// # Example
202 ///
203 /// ```
204 /// use jiff::civil::Weekday;
205 ///
206 /// let weekday = Weekday::from_sunday_one_offset(5)?;
207 /// assert_eq!(weekday, Weekday::Thursday);
208 ///
209 /// assert!(Weekday::from_sunday_one_offset(8).is_err());
210 /// assert!(Weekday::from_sunday_one_offset(0).is_err());
211 ///
212 /// # Ok::<(), Box<dyn std::error::Error>>(())
213 /// ```
214 #[inline]
215 pub fn from_sunday_one_offset(offset: i8) -> Result<Weekday, Error> {
216 jcore::civil::Weekday::from_sunday_one_offset(offset)
217 .map_err(Error::jcore_range)
218 .map(Weekday::from_jcore)
219 }
220
221 /// Returns this weekday as an offset.
222 ///
223 /// The offset returned is computed based on a week that starts with Monday
224 /// and begins numbering at `0`.
225 ///
226 /// # Example
227 ///
228 /// ```
229 /// use jiff::civil::Weekday;
230 ///
231 /// assert_eq!(Weekday::Thursday.to_monday_zero_offset(), 3);
232 ///
233 /// # Ok::<(), Box<dyn std::error::Error>>(())
234 /// ```
235 #[inline]
236 pub fn to_monday_zero_offset(self) -> i8 {
237 self.to_jcore().to_monday_zero_offset()
238 }
239
240 /// Returns this weekday as an offset.
241 ///
242 /// The offset returned is computed based on a week that starts with Monday
243 /// and begins numbering at `1`.
244 ///
245 /// # Example
246 ///
247 /// ```
248 /// use jiff::civil::Weekday;
249 ///
250 /// assert_eq!(Weekday::Thursday.to_monday_one_offset(), 4);
251 ///
252 /// # Ok::<(), Box<dyn std::error::Error>>(())
253 /// ```
254 #[inline]
255 pub fn to_monday_one_offset(self) -> i8 {
256 self.to_jcore().to_monday_one_offset()
257 }
258
259 /// Returns this weekday as an offset.
260 ///
261 /// The offset returned is computed based on a week that starts with Sunday
262 /// and begins numbering at `0`.
263 ///
264 /// # Example
265 ///
266 /// ```
267 /// use jiff::civil::Weekday;
268 ///
269 /// assert_eq!(Weekday::Thursday.to_sunday_zero_offset(), 4);
270 ///
271 /// # Ok::<(), Box<dyn std::error::Error>>(())
272 /// ```
273 #[inline]
274 pub fn to_sunday_zero_offset(self) -> i8 {
275 self.to_jcore().to_sunday_zero_offset()
276 }
277
278 /// Returns this weekday as an offset.
279 ///
280 /// The offset returned is computed based on a week that starts with Sunday
281 /// and begins numbering at `1`.
282 ///
283 /// # Example
284 ///
285 /// ```
286 /// use jiff::civil::Weekday;
287 ///
288 /// assert_eq!(Weekday::Thursday.to_sunday_one_offset(), 5);
289 ///
290 /// # Ok::<(), Box<dyn std::error::Error>>(())
291 /// ```
292 #[inline]
293 pub fn to_sunday_one_offset(self) -> i8 {
294 self.to_jcore().to_sunday_one_offset()
295 }
296
297 /// Returns the next weekday, wrapping around at the end of week to the
298 /// beginning of the week.
299 ///
300 /// This is a convenience routing for calling [`Weekday::wrapping_add`]
301 /// with a value of `1`.
302 ///
303 /// # Example
304 ///
305 /// ```
306 /// use jiff::civil::Weekday;
307 ///
308 /// assert_eq!(Weekday::Wednesday.next(), Weekday::Thursday);
309 /// assert_eq!(Weekday::Sunday.next(), Weekday::Monday);
310 /// assert_eq!(Weekday::Saturday.next(), Weekday::Sunday);
311 /// ```
312 #[inline]
313 pub fn next(self) -> Weekday {
314 self.wrapping_add(1)
315 }
316
317 /// Returns the previous weekday, wrapping around at the beginning of week
318 /// to the end of the week.
319 ///
320 /// This is a convenience routing for calling [`Weekday::wrapping_sub`]
321 /// with a value of `1`.
322 ///
323 /// # Example
324 ///
325 /// ```
326 /// use jiff::civil::Weekday;
327 ///
328 /// assert_eq!(Weekday::Wednesday.previous(), Weekday::Tuesday);
329 /// assert_eq!(Weekday::Sunday.previous(), Weekday::Saturday);
330 /// assert_eq!(Weekday::Saturday.previous(), Weekday::Friday);
331 /// ```
332 #[inline]
333 pub fn previous(self) -> Weekday {
334 self.wrapping_sub(1)
335 }
336
337 /// Returns the number of days from `other` to this weekday.
338 ///
339 /// Adding the returned number of days to `other` is guaranteed to sum to
340 /// this weekday. The number of days returned is guaranteed to be in the
341 /// range `0..=6`.
342 ///
343 /// # Example
344 ///
345 /// ```
346 /// use jiff::civil::Weekday;
347 ///
348 /// assert_eq!(Weekday::Friday.since(Weekday::Tuesday), 3);
349 /// assert_eq!(Weekday::Tuesday.since(Weekday::Tuesday), 0);
350 /// assert_eq!(Weekday::Monday.since(Weekday::Sunday), 1);
351 /// assert_eq!(Weekday::Sunday.since(Weekday::Monday), 6);
352 /// ```
353 #[inline]
354 pub fn since(self, other: Weekday) -> i8 {
355 self.to_jcore().since(other.to_jcore())
356 }
357
358 /// Returns the number of days until `other` from this weekday.
359 ///
360 /// Adding the returned number of days to this weekday is guaranteed to sum
361 /// to `other` weekday. The number of days returned is guaranteed to be in
362 /// the range `0..=6`.
363 ///
364 /// # Example
365 ///
366 /// ```
367 /// use jiff::civil::Weekday;
368 ///
369 /// assert_eq!(Weekday::Friday.until(Weekday::Tuesday), 4);
370 /// assert_eq!(Weekday::Tuesday.until(Weekday::Tuesday), 0);
371 /// assert_eq!(Weekday::Monday.until(Weekday::Sunday), 6);
372 /// assert_eq!(Weekday::Sunday.until(Weekday::Monday), 1);
373 /// ```
374 #[inline]
375 pub fn until(self, other: Weekday) -> i8 {
376 self.to_jcore().until(other.to_jcore())
377 }
378
379 /// Add the given number of days to this weekday, using wrapping arithmetic,
380 /// and return the resulting weekday.
381 ///
382 /// Adding a multiple of `7` (including `0`) is guaranteed to produce the
383 /// same weekday as this one.
384 ///
385 /// Note that this routine is also available via the `+` operator.
386 ///
387 /// # Example
388 ///
389 /// ```
390 /// use jiff::civil::Weekday;
391 ///
392 /// assert_eq!(Weekday::Sunday.wrapping_add(1), Weekday::Monday);
393 /// assert_eq!(Weekday::Sunday.wrapping_add(2), Weekday::Tuesday);
394 /// assert_eq!(Weekday::Saturday.wrapping_add(1), Weekday::Sunday);
395 /// assert_eq!(Weekday::Saturday.wrapping_add(7), Weekday::Saturday);
396 /// assert_eq!(Weekday::Sunday.wrapping_add(-1), Weekday::Saturday);
397 /// ```
398 ///
399 /// Wrapping arithmetic is also performed by the `+` operator:
400 ///
401 /// ```
402 /// use jiff::civil::Weekday;
403 ///
404 /// assert_eq!(Weekday::Sunday + 1, Weekday::Monday);
405 /// assert_eq!(Weekday::Sunday + 2, Weekday::Tuesday);
406 /// assert_eq!(Weekday::Saturday + 1, Weekday::Sunday);
407 /// assert_eq!(Weekday::Saturday + 7, Weekday::Saturday);
408 /// assert_eq!(Weekday::Sunday + -1, Weekday::Saturday);
409 /// // The weekday can also be on the right hand side of addition:
410 /// assert_eq!(1 + Weekday::Sunday, Weekday::Monday);
411 /// ```
412 #[inline]
413 pub fn wrapping_add<D: Into<i64>>(self, days: D) -> Weekday {
414 Weekday::from_jcore(self.to_jcore().wrapping_add(days.into()))
415 }
416
417 /// Subtract the given number of days from this weekday, using wrapping
418 /// arithmetic, and return the resulting weekday.
419 ///
420 /// Subtracting a multiple of `7` (including `0`) is guaranteed to produce
421 /// the same weekday as this one.
422 ///
423 /// Note that this routine is also available via the `-` operator.
424 ///
425 /// # Example
426 ///
427 /// ```
428 /// use jiff::civil::Weekday;
429 ///
430 /// assert_eq!(Weekday::Sunday.wrapping_sub(1), Weekday::Saturday);
431 /// assert_eq!(Weekday::Sunday.wrapping_sub(2), Weekday::Friday);
432 /// assert_eq!(Weekday::Saturday.wrapping_sub(1), Weekday::Friday);
433 /// assert_eq!(Weekday::Saturday.wrapping_sub(7), Weekday::Saturday);
434 /// assert_eq!(Weekday::Sunday.wrapping_sub(-1), Weekday::Monday);
435 /// ```
436 ///
437 /// Wrapping arithmetic is also performed by the `-` operator:
438 ///
439 /// ```
440 /// use jiff::civil::Weekday;
441 ///
442 /// assert_eq!(Weekday::Sunday - 1, Weekday::Saturday);
443 /// assert_eq!(Weekday::Sunday - 2, Weekday::Friday);
444 /// assert_eq!(Weekday::Saturday - 1, Weekday::Friday);
445 /// assert_eq!(Weekday::Saturday - 7, Weekday::Saturday);
446 /// assert_eq!(Weekday::Sunday - -1, Weekday::Monday);
447 /// ```
448 ///
449 /// Unlike addition, since subtraction is not commutative and negating a
450 /// weekday has no semantic meaning, the weekday cannot be on the right
451 /// hand side of the `-` operator.
452 #[inline]
453 pub fn wrapping_sub<D: Into<i64>>(self, days: D) -> Weekday {
454 Weekday::from_jcore(self.to_jcore().wrapping_sub(days.into()))
455 }
456
457 /// Starting with this weekday, this returns an unending iterator that
458 /// cycles forward through the days of the week.
459 ///
460 /// # Example
461 ///
462 /// ```
463 /// use jiff::civil::Weekday;
464 ///
465 /// let mut it = Weekday::Tuesday.cycle_forward();
466 /// assert_eq!(it.next(), Some(Weekday::Tuesday));
467 /// assert_eq!(it.next(), Some(Weekday::Wednesday));
468 /// assert_eq!(it.next(), Some(Weekday::Thursday));
469 /// assert_eq!(it.next(), Some(Weekday::Friday));
470 /// assert_eq!(it.next(), Some(Weekday::Saturday));
471 /// assert_eq!(it.next(), Some(Weekday::Sunday));
472 /// assert_eq!(it.next(), Some(Weekday::Monday));
473 /// assert_eq!(it.next(), Some(Weekday::Tuesday));
474 /// ```
475 #[inline]
476 pub fn cycle_forward(self) -> WeekdaysForward {
477 WeekdaysForward { it: self.to_jcore().cycle_forward() }
478 }
479
480 /// Starting with this weekday, this returns an unending iterator that
481 /// cycles backward through the days of the week.
482 ///
483 /// # Example
484 ///
485 /// ```
486 /// use jiff::civil::Weekday;
487 ///
488 /// let mut it = Weekday::Tuesday.cycle_reverse();
489 /// assert_eq!(it.next(), Some(Weekday::Tuesday));
490 /// assert_eq!(it.next(), Some(Weekday::Monday));
491 /// assert_eq!(it.next(), Some(Weekday::Sunday));
492 /// assert_eq!(it.next(), Some(Weekday::Saturday));
493 /// assert_eq!(it.next(), Some(Weekday::Friday));
494 /// assert_eq!(it.next(), Some(Weekday::Thursday));
495 /// assert_eq!(it.next(), Some(Weekday::Wednesday));
496 /// assert_eq!(it.next(), Some(Weekday::Tuesday));
497 /// ```
498 #[inline]
499 pub fn cycle_reverse(self) -> WeekdaysReverse {
500 WeekdaysReverse { it: self.to_jcore().cycle_reverse() }
501 }
502}
503
504impl Weekday {
505 #[inline]
506 pub(crate) const fn from_jcore(weekday: jcore::civil::Weekday) -> Weekday {
507 match weekday {
508 jcore::civil::Weekday::Monday => Weekday::Monday,
509 jcore::civil::Weekday::Tuesday => Weekday::Tuesday,
510 jcore::civil::Weekday::Wednesday => Weekday::Wednesday,
511 jcore::civil::Weekday::Thursday => Weekday::Thursday,
512 jcore::civil::Weekday::Friday => Weekday::Friday,
513 jcore::civil::Weekday::Saturday => Weekday::Saturday,
514 jcore::civil::Weekday::Sunday => Weekday::Sunday,
515 }
516 }
517
518 #[inline]
519 pub(crate) const fn to_jcore(self) -> jcore::civil::Weekday {
520 match self {
521 Weekday::Monday => jcore::civil::Weekday::Monday,
522 Weekday::Tuesday => jcore::civil::Weekday::Tuesday,
523 Weekday::Wednesday => jcore::civil::Weekday::Wednesday,
524 Weekday::Thursday => jcore::civil::Weekday::Thursday,
525 Weekday::Friday => jcore::civil::Weekday::Friday,
526 Weekday::Saturday => jcore::civil::Weekday::Saturday,
527 Weekday::Sunday => jcore::civil::Weekday::Sunday,
528 }
529 }
530}
531
532impl core::ops::Add<i8> for Weekday {
533 type Output = Weekday;
534
535 #[inline]
536 fn add(self, rhs: i8) -> Weekday {
537 self.wrapping_add(rhs)
538 }
539}
540
541impl core::ops::Add<i16> for Weekday {
542 type Output = Weekday;
543
544 #[inline]
545 fn add(self, rhs: i16) -> Weekday {
546 self.wrapping_add(rhs)
547 }
548}
549
550impl core::ops::Add<i32> for Weekday {
551 type Output = Weekday;
552
553 #[inline]
554 fn add(self, rhs: i32) -> Weekday {
555 self.wrapping_add(rhs)
556 }
557}
558
559impl core::ops::Add<i64> for Weekday {
560 type Output = Weekday;
561
562 #[inline]
563 fn add(self, rhs: i64) -> Weekday {
564 self.wrapping_add(rhs)
565 }
566}
567
568// Since addition is commutative, we don't care if users write `n + weekday`
569// or `weekday + n`.
570
571impl core::ops::Add<Weekday> for i8 {
572 type Output = Weekday;
573
574 #[inline]
575 fn add(self, rhs: Weekday) -> Weekday {
576 rhs.wrapping_add(self)
577 }
578}
579
580impl core::ops::Add<Weekday> for i16 {
581 type Output = Weekday;
582
583 #[inline]
584 fn add(self, rhs: Weekday) -> Weekday {
585 rhs.wrapping_add(self)
586 }
587}
588
589impl core::ops::Add<Weekday> for i32 {
590 type Output = Weekday;
591
592 #[inline]
593 fn add(self, rhs: Weekday) -> Weekday {
594 rhs.wrapping_add(self)
595 }
596}
597
598impl core::ops::Add<Weekday> for i64 {
599 type Output = Weekday;
600
601 #[inline]
602 fn add(self, rhs: Weekday) -> Weekday {
603 rhs.wrapping_add(self)
604 }
605}
606
607impl core::ops::AddAssign<i8> for Weekday {
608 #[inline]
609 fn add_assign(&mut self, rhs: i8) {
610 *self = *self + rhs;
611 }
612}
613
614impl core::ops::AddAssign<i16> for Weekday {
615 #[inline]
616 fn add_assign(&mut self, rhs: i16) {
617 *self = *self + rhs;
618 }
619}
620
621impl core::ops::AddAssign<i32> for Weekday {
622 #[inline]
623 fn add_assign(&mut self, rhs: i32) {
624 *self = *self + rhs;
625 }
626}
627
628impl core::ops::AddAssign<i64> for Weekday {
629 #[inline]
630 fn add_assign(&mut self, rhs: i64) {
631 *self = *self + rhs;
632 }
633}
634
635// Subtraction isn't commutative, so we only define it when the right hand
636// side is an integer. Otherwise we'd need a concept of what it means to
637// "negate" a weekday, which doesn't really make sense?
638
639impl core::ops::Sub<i8> for Weekday {
640 type Output = Weekday;
641
642 #[inline]
643 fn sub(self, rhs: i8) -> Weekday {
644 self.wrapping_sub(rhs)
645 }
646}
647
648impl core::ops::Sub<i16> for Weekday {
649 type Output = Weekday;
650
651 #[inline]
652 fn sub(self, rhs: i16) -> Weekday {
653 self.wrapping_sub(rhs)
654 }
655}
656
657impl core::ops::Sub<i32> for Weekday {
658 type Output = Weekday;
659
660 #[inline]
661 fn sub(self, rhs: i32) -> Weekday {
662 self.wrapping_sub(rhs)
663 }
664}
665
666impl core::ops::Sub<i64> for Weekday {
667 type Output = Weekday;
668
669 #[inline]
670 fn sub(self, rhs: i64) -> Weekday {
671 self.wrapping_sub(rhs)
672 }
673}
674
675impl core::ops::SubAssign<i8> for Weekday {
676 #[inline]
677 fn sub_assign(&mut self, rhs: i8) {
678 *self = *self - rhs;
679 }
680}
681
682impl core::ops::SubAssign<i16> for Weekday {
683 #[inline]
684 fn sub_assign(&mut self, rhs: i16) {
685 *self = *self - rhs;
686 }
687}
688
689impl core::ops::SubAssign<i32> for Weekday {
690 #[inline]
691 fn sub_assign(&mut self, rhs: i32) {
692 *self = *self - rhs;
693 }
694}
695
696impl core::ops::SubAssign<i64> for Weekday {
697 #[inline]
698 fn sub_assign(&mut self, rhs: i64) {
699 *self = *self - rhs;
700 }
701}
702
703#[cfg(test)]
704impl quickcheck::Arbitrary for Weekday {
705 fn arbitrary(g: &mut quickcheck::Gen) -> Weekday {
706 let offset = crate::util::b::WeekdayMondayZero::arbitrary(g);
707 Weekday::from_monday_zero_offset(offset).unwrap()
708 }
709
710 fn shrink(&self) -> alloc::boxed::Box<dyn Iterator<Item = Weekday>> {
711 alloc::boxed::Box::new(
712 self.to_monday_zero_offset()
713 .shrink()
714 .filter_map(|n| Weekday::from_monday_zero_offset(n).ok()),
715 )
716 }
717}
718
719/// An unending iterator of the days of the week.
720///
721/// This iterator is created by calling [`Weekday::cycle_forward`].
722#[derive(Clone, Debug)]
723pub struct WeekdaysForward {
724 it: jcore::civil::WeekdaysForward,
725}
726
727impl Iterator for WeekdaysForward {
728 type Item = Weekday;
729
730 #[inline]
731 fn next(&mut self) -> Option<Weekday> {
732 self.it.next().map(Weekday::from_jcore)
733 }
734}
735
736impl core::iter::FusedIterator for WeekdaysForward {}
737
738/// An unending iterator of the days of the week in reverse.
739///
740/// This iterator is created by calling [`Weekday::cycle_reverse`].
741#[derive(Clone, Debug)]
742pub struct WeekdaysReverse {
743 it: jcore::civil::WeekdaysReverse,
744}
745
746impl Iterator for WeekdaysReverse {
747 type Item = Weekday;
748
749 #[inline]
750 fn next(&mut self) -> Option<Weekday> {
751 self.it.next().map(Weekday::from_jcore)
752 }
753}
754
755impl core::iter::FusedIterator for WeekdaysReverse {}