tz/error/
parse.rs

1//! Parsing error types.
2
3use core::error::Error;
4use core::fmt;
5use core::num::ParseIntError;
6use core::str::Utf8Error;
7
8/// Parse data error
9#[non_exhaustive]
10#[derive(Debug)]
11pub enum ParseDataError {
12    /// Unexpected end of data
13    UnexpectedEof,
14    /// Invalid data
15    InvalidData,
16}
17
18impl fmt::Display for ParseDataError {
19    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
20        match self {
21            Self::UnexpectedEof => f.write_str("unexpected end of data"),
22            Self::InvalidData => f.write_str("invalid data"),
23        }
24    }
25}
26
27impl Error for ParseDataError {}
28
29/// Unified error type for parsing a TZ string
30#[non_exhaustive]
31#[derive(Debug)]
32pub enum TzStringError {
33    /// UTF-8 error
34    Utf8(Utf8Error),
35    /// Integer parsing error
36    ParseInt(ParseIntError),
37    /// Parse data error
38    ParseData(ParseDataError),
39    /// Invalid offset hour
40    InvalidOffsetHour,
41    /// Invalid offset minute
42    InvalidOffsetMinute,
43    /// Invalid offset second
44    InvalidOffsetSecond,
45    /// Invalid day time hour
46    InvalidDayTimeHour,
47    /// Invalid day time minute
48    InvalidDayTimeMinute,
49    /// Invalid day time second
50    InvalidDayTimeSecond,
51    /// Missing DST start and end rules
52    MissingDstStartEndRules,
53    /// Remaining data was found after parsing TZ string
54    RemainingData,
55    /// Empty TZ string
56    Empty,
57}
58
59impl fmt::Display for TzStringError {
60    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
61        match self {
62            Self::Utf8(error) => error.fmt(f),
63            Self::ParseInt(error) => error.fmt(f),
64            Self::ParseData(error) => error.fmt(f),
65            Self::InvalidOffsetHour => f.write_str("invalid offset hour"),
66            Self::InvalidOffsetMinute => f.write_str("invalid offset minute"),
67            Self::InvalidOffsetSecond => f.write_str("invalid offset second"),
68            Self::InvalidDayTimeHour => f.write_str("invalid day time hour"),
69            Self::InvalidDayTimeMinute => f.write_str("invalid day time minute"),
70            Self::InvalidDayTimeSecond => f.write_str("invalid day time second"),
71            Self::MissingDstStartEndRules => f.write_str("missing DST start and end rules"),
72            Self::RemainingData => f.write_str("remaining data after parsing TZ string"),
73            Self::Empty => f.write_str("empty TZ string"),
74        }
75    }
76}
77
78impl Error for TzStringError {}
79
80impl From<Utf8Error> for TzStringError {
81    fn from(error: Utf8Error) -> Self {
82        Self::Utf8(error)
83    }
84}
85
86impl From<ParseIntError> for TzStringError {
87    fn from(error: ParseIntError) -> Self {
88        Self::ParseInt(error)
89    }
90}
91
92impl From<ParseDataError> for TzStringError {
93    fn from(error: ParseDataError) -> Self {
94        Self::ParseData(error)
95    }
96}
97
98/// Unified error type for parsing a TZif file
99#[non_exhaustive]
100#[derive(Debug)]
101pub enum TzFileError {
102    /// UTF-8 error
103    Utf8(Utf8Error),
104    /// Parse data error
105    ParseData(ParseDataError),
106    /// Invalid magic number
107    InvalidMagicNumber,
108    /// Unsupported TZif version
109    UnsupportedTzFileVersion,
110    /// Invalid header
111    InvalidHeader,
112    /// Invalid footer
113    InvalidFooter,
114    /// Invalid DST indicator
115    InvalidDstIndicator,
116    /// Invalid time zone designation char index
117    InvalidTimeZoneDesignationCharIndex,
118    /// Invalid couple of standard/wall and UT/local indicators
119    InvalidStdWallUtLocal,
120    /// Remaining data after the end of a TZif v1 data block
121    RemainingDataV1,
122}
123
124impl fmt::Display for TzFileError {
125    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
126        match self {
127            Self::Utf8(error) => error.fmt(f),
128            Self::ParseData(error) => error.fmt(f),
129            Self::InvalidMagicNumber => f.write_str("invalid magic number"),
130            Self::UnsupportedTzFileVersion => write!(f, "unsupported TZ file version"),
131            Self::InvalidHeader => f.write_str("invalid header"),
132            Self::InvalidFooter => f.write_str("invalid footer"),
133            Self::InvalidDstIndicator => f.write_str("invalid DST indicator"),
134            Self::InvalidTimeZoneDesignationCharIndex => f.write_str("invalid time zone designation char index"),
135            Self::InvalidStdWallUtLocal => f.write_str("invalid couple of standard/wall and UT/local indicators"),
136            Self::RemainingDataV1 => f.write_str("remaining data after the end of a TZif v1 data block"),
137        }
138    }
139}
140
141impl Error for TzFileError {}
142
143impl From<Utf8Error> for TzFileError {
144    fn from(error: Utf8Error) -> Self {
145        Self::Utf8(error)
146    }
147}
148
149impl From<ParseDataError> for TzFileError {
150    fn from(error: ParseDataError) -> Self {
151        Self::ParseData(error)
152    }
153}