icu_calendar/error.rs
1// This file is part of ICU4X. For terms of use, please see the file
2// called LICENSE at the top level of the ICU4X source tree
3// (online at: https://github.com/unicode-org/icu4x/blob/main/LICENSE ).
4
5use displaydoc::Display;
6use icu_provider::DataError;
7use tinystr::{tinystr, TinyStr16, TinyStr4};
8use writeable::Writeable;
9
10#[cfg(feature = "std")]
11impl std::error::Error for CalendarError {}
12
13/// A list of error outcomes for various operations in this module.
14///
15/// Re-exported as [`Error`](crate::Error).
16#[derive(Display, Debug, Copy, Clone, PartialEq)]
17#[non_exhaustive]
18pub enum CalendarError {
19 /// An input could not be parsed.
20 #[displaydoc("Could not parse as integer")]
21 Parse,
22 /// An input overflowed its range.
23 #[displaydoc("{field} must be between 0-{max}")]
24 Overflow {
25 /// The name of the field
26 field: &'static str,
27 /// The maximum value
28 max: usize,
29 },
30 #[displaydoc("{field} must be between {min}-0")]
31 /// An input underflowed its range.
32 Underflow {
33 /// The name of the field
34 field: &'static str,
35 /// The minimum value
36 min: isize,
37 },
38 /// Out of range
39 // TODO(Manishearth) turn this into a proper variant
40 OutOfRange,
41 /// Unknown era
42 #[displaydoc("No era named {0} for calendar {1}")]
43 UnknownEra(TinyStr16, &'static str),
44 /// Unknown month code for a given calendar
45 #[displaydoc("No month code named {0} for calendar {1}")]
46 UnknownMonthCode(TinyStr4, &'static str),
47 /// Missing required input field for formatting
48 #[displaydoc("No value for {0}")]
49 MissingInput(&'static str),
50 /// No support for a given calendar in AnyCalendar
51 #[displaydoc("AnyCalendar does not support calendar {0}")]
52 UnknownAnyCalendarKind(TinyStr16),
53 /// An operation required a calendar but a calendar was not provided.
54 #[displaydoc("An operation required a calendar but a calendar was not provided")]
55 MissingCalendar,
56 /// An error originating inside of the [data provider](icu_provider).
57 #[displaydoc("{0}")]
58 Data(DataError),
59}
60
61impl From<core::num::ParseIntError> for CalendarError {
62 fn from(_: core::num::ParseIntError) -> Self {
63 CalendarError::Parse
64 }
65}
66
67impl From<DataError> for CalendarError {
68 fn from(e: DataError) -> Self {
69 CalendarError::Data(e)
70 }
71}
72
73impl CalendarError {
74 /// Create an error when an [`AnyCalendarKind`] is expected but not available.
75 ///
76 /// # Examples
77 ///
78 /// ```
79 /// use icu::calendar::AnyCalendarKind;
80 /// use icu::calendar::CalendarError;
81 ///
82 /// let cal_str = "maori";
83 ///
84 /// AnyCalendarKind::get_for_bcp47_string(cal_str)
85 /// .ok_or_else(|| CalendarError::unknown_any_calendar_kind(cal_str))
86 /// .expect_err("Māori calendar is not yet supported");
87 /// ```
88 ///
89 /// [`AnyCalendarKind`]: crate::AnyCalendarKind
90 pub fn unknown_any_calendar_kind(description: impl Writeable) -> Self {
91 let tiny = description
92 .write_to_string()
93 .get(0..16)
94 .and_then(|x| TinyStr16::from_str(x).ok())
95 .unwrap_or(tinystr!(16, "invalid"));
96 Self::UnknownAnyCalendarKind(tiny)
97 }
98}