1#![deny(missing_docs)]
2#![allow(dead_code)]
3#![warn(unreachable_pub)]
4
5use std::num::ParseIntError;
6use std::str::Utf8Error;
7use std::time::SystemTimeError;
8use std::{error, fmt, io};
9
10mod timezone;
11pub(crate) use timezone::TimeZone;
12
13mod parser;
14mod rule;
15
16/// Unified error type for everything in the crate
17#[derive(Debug)]
18pub(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
53impl fmt::Display for Error {
54 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
55 use Error::*;
56 match self {
57 DateTime(error: &&str) => write!(f, "invalid date time: {}", error),
58 FindLocalTimeType(error: &&str) => error.fmt(f),
59 LocalTimeType(error: &&str) => write!(f, "invalid local time type: {}", error),
60 InvalidSlice(error: &&str) => error.fmt(f),
61 InvalidTzString(error: &&str) => write!(f, "invalid TZ string: {}", error),
62 InvalidTzFile(error: &&str) => error.fmt(f),
63 Io(error: &Error) => error.fmt(f),
64 OutOfRange(error: &&str) => error.fmt(f),
65 ParseInt(error: &ParseIntError) => error.fmt(f),
66 ProjectDateTime(error: &&str) => error.fmt(f),
67 SystemTime(error: &SystemTimeError) => error.fmt(f),
68 TransitionRule(error: &&str) => write!(f, "invalid transition rule: {}", error),
69 TimeZone(error: &&str) => write!(f, "invalid time zone: {}", error),
70 UnsupportedTzFile(error: &&str) => error.fmt(f),
71 UnsupportedTzString(error: &&str) => write!(f, "unsupported TZ string: {}", error),
72 Utf8(error: &Utf8Error) => error.fmt(f),
73 }
74 }
75}
76
77impl error::Error for Error {}
78
79impl From<io::Error> for Error {
80 fn from(error: io::Error) -> Self {
81 Error::Io(error)
82 }
83}
84
85impl From<ParseIntError> for Error {
86 fn from(error: ParseIntError) -> Self {
87 Error::ParseInt(error)
88 }
89}
90
91impl From<SystemTimeError> for Error {
92 fn from(error: SystemTimeError) -> Self {
93 Error::SystemTime(error)
94 }
95}
96
97impl From<Utf8Error> for Error {
98 fn from(error: Utf8Error) -> Self {
99 Error::Utf8(error)
100 }
101}
102
103/// Number of hours in one day
104const HOURS_PER_DAY: i64 = 24;
105/// Number of seconds in one hour
106const SECONDS_PER_HOUR: i64 = 3600;
107/// Number of seconds in one day
108const SECONDS_PER_DAY: i64 = SECONDS_PER_HOUR * HOURS_PER_DAY;
109/// Number of days in one week
110const DAYS_PER_WEEK: i64 = 7;
111
112/// Month days in a normal year
113const 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
115const CUMUL_DAY_IN_MONTHS_NORMAL_YEAR: [i64; 12] =
116 [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
117