summaryrefslogtreecommitdiffstats
path: root/vendor/chrono/src/weekday.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/chrono/src/weekday.rs')
-rw-r--r--vendor/chrono/src/weekday.rs329
1 files changed, 329 insertions, 0 deletions
diff --git a/vendor/chrono/src/weekday.rs b/vendor/chrono/src/weekday.rs
new file mode 100644
index 000000000..72e384673
--- /dev/null
+++ b/vendor/chrono/src/weekday.rs
@@ -0,0 +1,329 @@
+use core::fmt;
+
+#[cfg(feature = "rkyv")]
+use rkyv::{Archive, Deserialize, Serialize};
+
+/// The day of week.
+///
+/// The order of the days of week depends on the context.
+/// (This is why this type does *not* implement `PartialOrd` or `Ord` traits.)
+/// One should prefer `*_from_monday` or `*_from_sunday` methods to get the correct result.
+#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)]
+#[cfg_attr(feature = "rustc-serialize", derive(RustcEncodable, RustcDecodable))]
+#[cfg_attr(feature = "rkyv", derive(Archive, Deserialize, Serialize))]
+#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
+pub enum Weekday {
+ /// Monday.
+ Mon = 0,
+ /// Tuesday.
+ Tue = 1,
+ /// Wednesday.
+ Wed = 2,
+ /// Thursday.
+ Thu = 3,
+ /// Friday.
+ Fri = 4,
+ /// Saturday.
+ Sat = 5,
+ /// Sunday.
+ Sun = 6,
+}
+
+impl Weekday {
+ /// The next day in the week.
+ ///
+ /// `w`: | `Mon` | `Tue` | `Wed` | `Thu` | `Fri` | `Sat` | `Sun`
+ /// ----------- | ----- | ----- | ----- | ----- | ----- | ----- | -----
+ /// `w.succ()`: | `Tue` | `Wed` | `Thu` | `Fri` | `Sat` | `Sun` | `Mon`
+ #[inline]
+ pub fn succ(&self) -> Weekday {
+ match *self {
+ Weekday::Mon => Weekday::Tue,
+ Weekday::Tue => Weekday::Wed,
+ Weekday::Wed => Weekday::Thu,
+ Weekday::Thu => Weekday::Fri,
+ Weekday::Fri => Weekday::Sat,
+ Weekday::Sat => Weekday::Sun,
+ Weekday::Sun => Weekday::Mon,
+ }
+ }
+
+ /// The previous day in the week.
+ ///
+ /// `w`: | `Mon` | `Tue` | `Wed` | `Thu` | `Fri` | `Sat` | `Sun`
+ /// ----------- | ----- | ----- | ----- | ----- | ----- | ----- | -----
+ /// `w.pred()`: | `Sun` | `Mon` | `Tue` | `Wed` | `Thu` | `Fri` | `Sat`
+ #[inline]
+ pub fn pred(&self) -> Weekday {
+ match *self {
+ Weekday::Mon => Weekday::Sun,
+ Weekday::Tue => Weekday::Mon,
+ Weekday::Wed => Weekday::Tue,
+ Weekday::Thu => Weekday::Wed,
+ Weekday::Fri => Weekday::Thu,
+ Weekday::Sat => Weekday::Fri,
+ Weekday::Sun => Weekday::Sat,
+ }
+ }
+
+ /// Returns a day-of-week number starting from Monday = 1. (ISO 8601 weekday number)
+ ///
+ /// `w`: | `Mon` | `Tue` | `Wed` | `Thu` | `Fri` | `Sat` | `Sun`
+ /// ------------------------- | ----- | ----- | ----- | ----- | ----- | ----- | -----
+ /// `w.number_from_monday()`: | 1 | 2 | 3 | 4 | 5 | 6 | 7
+ #[inline]
+ pub const fn number_from_monday(&self) -> u32 {
+ self.num_days_from(Weekday::Mon) + 1
+ }
+
+ /// Returns a day-of-week number starting from Sunday = 1.
+ ///
+ /// `w`: | `Mon` | `Tue` | `Wed` | `Thu` | `Fri` | `Sat` | `Sun`
+ /// ------------------------- | ----- | ----- | ----- | ----- | ----- | ----- | -----
+ /// `w.number_from_sunday()`: | 2 | 3 | 4 | 5 | 6 | 7 | 1
+ #[inline]
+ pub const fn number_from_sunday(&self) -> u32 {
+ self.num_days_from(Weekday::Sun) + 1
+ }
+
+ /// Returns a day-of-week number starting from Monday = 0.
+ ///
+ /// `w`: | `Mon` | `Tue` | `Wed` | `Thu` | `Fri` | `Sat` | `Sun`
+ /// --------------------------- | ----- | ----- | ----- | ----- | ----- | ----- | -----
+ /// `w.num_days_from_monday()`: | 0 | 1 | 2 | 3 | 4 | 5 | 6
+ #[inline]
+ pub const fn num_days_from_monday(&self) -> u32 {
+ self.num_days_from(Weekday::Mon)
+ }
+
+ /// Returns a day-of-week number starting from Sunday = 0.
+ ///
+ /// `w`: | `Mon` | `Tue` | `Wed` | `Thu` | `Fri` | `Sat` | `Sun`
+ /// --------------------------- | ----- | ----- | ----- | ----- | ----- | ----- | -----
+ /// `w.num_days_from_sunday()`: | 1 | 2 | 3 | 4 | 5 | 6 | 0
+ #[inline]
+ pub const fn num_days_from_sunday(&self) -> u32 {
+ self.num_days_from(Weekday::Sun)
+ }
+
+ /// Returns a day-of-week number starting from the parameter `day` (D) = 0.
+ ///
+ /// `w`: | `D` | `D+1` | `D+2` | `D+3` | `D+4` | `D+5` | `D+6`
+ /// --------------------------- | ----- | ----- | ----- | ----- | ----- | ----- | -----
+ /// `w.num_days_from(wd)`: | 0 | 1 | 2 | 3 | 4 | 5 | 6
+ #[inline]
+ pub(crate) const fn num_days_from(&self, day: Weekday) -> u32 {
+ (*self as u32 + 7 - day as u32) % 7
+ }
+}
+
+impl fmt::Display for Weekday {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str(match *self {
+ Weekday::Mon => "Mon",
+ Weekday::Tue => "Tue",
+ Weekday::Wed => "Wed",
+ Weekday::Thu => "Thu",
+ Weekday::Fri => "Fri",
+ Weekday::Sat => "Sat",
+ Weekday::Sun => "Sun",
+ })
+ }
+}
+
+/// Any weekday can be represented as an integer from 0 to 6, which equals to
+/// [`Weekday::num_days_from_monday`](#method.num_days_from_monday) in this implementation.
+/// Do not heavily depend on this though; use explicit methods whenever possible.
+impl num_traits::FromPrimitive for Weekday {
+ #[inline]
+ fn from_i64(n: i64) -> Option<Weekday> {
+ match n {
+ 0 => Some(Weekday::Mon),
+ 1 => Some(Weekday::Tue),
+ 2 => Some(Weekday::Wed),
+ 3 => Some(Weekday::Thu),
+ 4 => Some(Weekday::Fri),
+ 5 => Some(Weekday::Sat),
+ 6 => Some(Weekday::Sun),
+ _ => None,
+ }
+ }
+
+ #[inline]
+ fn from_u64(n: u64) -> Option<Weekday> {
+ match n {
+ 0 => Some(Weekday::Mon),
+ 1 => Some(Weekday::Tue),
+ 2 => Some(Weekday::Wed),
+ 3 => Some(Weekday::Thu),
+ 4 => Some(Weekday::Fri),
+ 5 => Some(Weekday::Sat),
+ 6 => Some(Weekday::Sun),
+ _ => None,
+ }
+ }
+}
+
+/// An error resulting from reading `Weekday` value with `FromStr`.
+#[derive(Clone, PartialEq, Eq)]
+pub struct ParseWeekdayError {
+ pub(crate) _dummy: (),
+}
+
+#[cfg(feature = "std")]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+impl std::error::Error for ParseWeekdayError {}
+
+impl fmt::Display for ParseWeekdayError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_fmt(format_args!("{:?}", self))
+ }
+}
+
+impl fmt::Debug for ParseWeekdayError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(f, "ParseWeekdayError {{ .. }}")
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use num_traits::FromPrimitive;
+
+ use super::Weekday;
+
+ #[test]
+ fn test_num_days_from() {
+ for i in 0..7 {
+ let base_day = Weekday::from_u64(i).unwrap();
+
+ assert_eq!(base_day.num_days_from_monday(), base_day.num_days_from(Weekday::Mon));
+ assert_eq!(base_day.num_days_from_sunday(), base_day.num_days_from(Weekday::Sun));
+
+ assert_eq!(base_day.num_days_from(base_day), 0);
+
+ assert_eq!(base_day.num_days_from(base_day.pred()), 1);
+ assert_eq!(base_day.num_days_from(base_day.pred().pred()), 2);
+ assert_eq!(base_day.num_days_from(base_day.pred().pred().pred()), 3);
+ assert_eq!(base_day.num_days_from(base_day.pred().pred().pred().pred()), 4);
+ assert_eq!(base_day.num_days_from(base_day.pred().pred().pred().pred().pred()), 5);
+ assert_eq!(
+ base_day.num_days_from(base_day.pred().pred().pred().pred().pred().pred()),
+ 6
+ );
+
+ assert_eq!(base_day.num_days_from(base_day.succ()), 6);
+ assert_eq!(base_day.num_days_from(base_day.succ().succ()), 5);
+ assert_eq!(base_day.num_days_from(base_day.succ().succ().succ()), 4);
+ assert_eq!(base_day.num_days_from(base_day.succ().succ().succ().succ()), 3);
+ assert_eq!(base_day.num_days_from(base_day.succ().succ().succ().succ().succ()), 2);
+ assert_eq!(
+ base_day.num_days_from(base_day.succ().succ().succ().succ().succ().succ()),
+ 1
+ );
+ }
+ }
+}
+
+// the actual `FromStr` implementation is in the `format` module to leverage the existing code
+
+#[cfg(feature = "serde")]
+#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
+mod weekday_serde {
+ use super::Weekday;
+ use core::fmt;
+ use serde::{de, ser};
+
+ impl ser::Serialize for Weekday {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: ser::Serializer,
+ {
+ serializer.collect_str(&self)
+ }
+ }
+
+ struct WeekdayVisitor;
+
+ impl<'de> de::Visitor<'de> for WeekdayVisitor {
+ type Value = Weekday;
+
+ fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str("Weekday")
+ }
+
+ fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ value.parse().map_err(|_| E::custom("short or long weekday names expected"))
+ }
+ }
+
+ impl<'de> de::Deserialize<'de> for Weekday {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ deserializer.deserialize_str(WeekdayVisitor)
+ }
+ }
+
+ #[test]
+ fn test_serde_serialize() {
+ use serde_json::to_string;
+ use Weekday::*;
+
+ let cases: Vec<(Weekday, &str)> = vec![
+ (Mon, "\"Mon\""),
+ (Tue, "\"Tue\""),
+ (Wed, "\"Wed\""),
+ (Thu, "\"Thu\""),
+ (Fri, "\"Fri\""),
+ (Sat, "\"Sat\""),
+ (Sun, "\"Sun\""),
+ ];
+
+ for (weekday, expected_str) in cases {
+ let string = to_string(&weekday).unwrap();
+ assert_eq!(string, expected_str);
+ }
+ }
+
+ #[test]
+ fn test_serde_deserialize() {
+ use serde_json::from_str;
+ use Weekday::*;
+
+ let cases: Vec<(&str, Weekday)> = vec![
+ ("\"mon\"", Mon),
+ ("\"MONDAY\"", Mon),
+ ("\"MonDay\"", Mon),
+ ("\"mOn\"", Mon),
+ ("\"tue\"", Tue),
+ ("\"tuesday\"", Tue),
+ ("\"wed\"", Wed),
+ ("\"wednesday\"", Wed),
+ ("\"thu\"", Thu),
+ ("\"thursday\"", Thu),
+ ("\"fri\"", Fri),
+ ("\"friday\"", Fri),
+ ("\"sat\"", Sat),
+ ("\"saturday\"", Sat),
+ ("\"sun\"", Sun),
+ ("\"sunday\"", Sun),
+ ];
+
+ for (str, expected_weekday) in cases {
+ let weekday = from_str::<Weekday>(str).unwrap();
+ assert_eq!(weekday, expected_weekday);
+ }
+
+ let errors: Vec<&str> =
+ vec!["\"not a weekday\"", "\"monDAYs\"", "\"mond\"", "mon", "\"thur\"", "\"thurs\""];
+
+ for str in errors {
+ from_str::<Weekday>(str).unwrap_err();
+ }
+ }
+}