1 #![deny(missing_docs)] 2 #![allow(dead_code)] 3 #![warn(unreachable_pub)] 4 5 use std::num::ParseIntError; 6 use std::str::Utf8Error; 7 use std::time::SystemTimeError; 8 use std::{error, fmt, io}; 9 10 mod timezone; 11 pub(crate) use timezone::TimeZone; 12 13 mod parser; 14 mod rule; 15 16 /// Unified error type for everything in the crate 17 #[derive(Debug)] 18 pub(crate) enum Error { 19 /// Date time error 20 DateTime(&'static str), 21 /// Local time type search error 22 FindLocalTimeType(&'static str), 23 /// Local time type error 24 LocalTimeType(&'static str), 25 /// Invalid slice for integer conversion 26 InvalidSlice(&'static str), 27 /// Invalid Tzif file 28 InvalidTzFile(&'static str), 29 /// Invalid TZ string 30 InvalidTzString(&'static str), 31 /// I/O error 32 Io(io::Error), 33 /// Out of range error 34 OutOfRange(&'static str), 35 /// Integer parsing error 36 ParseInt(ParseIntError), 37 /// Date time projection error 38 ProjectDateTime(&'static str), 39 /// System time error 40 SystemTime(SystemTimeError), 41 /// Time zone error 42 TimeZone(&'static str), 43 /// Transition rule error 44 TransitionRule(&'static str), 45 /// Unsupported Tzif file 46 UnsupportedTzFile(&'static str), 47 /// Unsupported TZ string 48 UnsupportedTzString(&'static str), 49 /// UTF-8 error 50 Utf8(Utf8Error), 51 } 52 53 impl fmt::Display for Error { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result54 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 55 use Error::*; 56 match self { 57 DateTime(error) => write!(f, "invalid date time: {}", error), 58 FindLocalTimeType(error) => error.fmt(f), 59 LocalTimeType(error) => write!(f, "invalid local time type: {}", error), 60 InvalidSlice(error) => error.fmt(f), 61 InvalidTzString(error) => write!(f, "invalid TZ string: {}", error), 62 InvalidTzFile(error) => error.fmt(f), 63 Io(error) => error.fmt(f), 64 OutOfRange(error) => error.fmt(f), 65 ParseInt(error) => error.fmt(f), 66 ProjectDateTime(error) => error.fmt(f), 67 SystemTime(error) => error.fmt(f), 68 TransitionRule(error) => write!(f, "invalid transition rule: {}", error), 69 TimeZone(error) => write!(f, "invalid time zone: {}", error), 70 UnsupportedTzFile(error) => error.fmt(f), 71 UnsupportedTzString(error) => write!(f, "unsupported TZ string: {}", error), 72 Utf8(error) => error.fmt(f), 73 } 74 } 75 } 76 77 impl error::Error for Error {} 78 79 impl From<io::Error> for Error { from(error: io::Error) -> Self80 fn from(error: io::Error) -> Self { 81 Error::Io(error) 82 } 83 } 84 85 impl From<ParseIntError> for Error { from(error: ParseIntError) -> Self86 fn from(error: ParseIntError) -> Self { 87 Error::ParseInt(error) 88 } 89 } 90 91 impl From<SystemTimeError> for Error { from(error: SystemTimeError) -> Self92 fn from(error: SystemTimeError) -> Self { 93 Error::SystemTime(error) 94 } 95 } 96 97 impl From<Utf8Error> for Error { from(error: Utf8Error) -> Self98 fn from(error: Utf8Error) -> Self { 99 Error::Utf8(error) 100 } 101 } 102 103 /// Number of hours in one day 104 const HOURS_PER_DAY: i64 = 24; 105 /// Number of seconds in one hour 106 const SECONDS_PER_HOUR: i64 = 3600; 107 /// Number of seconds in one day 108 const SECONDS_PER_DAY: i64 = SECONDS_PER_HOUR * HOURS_PER_DAY; 109 /// Number of days in one week 110 const DAYS_PER_WEEK: i64 = 7; 111 112 /// Month days in a normal year 113 const DAY_IN_MONTHS_NORMAL_YEAR: [i64; 12] = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; 114 /// Cumulated month days in a normal year 115 const CUMUL_DAY_IN_MONTHS_NORMAL_YEAR: [i64; 12] = 116 [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]; 117