Skip to main content

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 {}