Skip to main content

icu_capi/
errors.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 ffi::*;
6
7#[diplomat::bridge]
8#[diplomat::abi_rename = "icu4x_{0}_mv1"]
9pub mod ffi {
10    #[cfg(feature = "datetime")]
11    use diplomat_runtime::DiplomatOption;
12
13    #[cfg(feature = "datetime")]
14    use crate::unstable::calendar::ffi::CalendarKind;
15
16    #[derive(Debug, PartialEq, Eq)]
17    #[repr(C)]
18    #[diplomat::rust_link(icu_provider::DataError, Struct, compact)]
19    #[diplomat::rust_link(icu_provider::DataErrorKind, Enum, compact)]
20    #[non_exhaustive]
21    pub enum DataError {
22        Unknown = 0x00,
23        MarkerNotFound = 0x01,
24        IdentifierNotFound = 0x02,
25        InvalidRequest = 0x03,
26        InconsistentData = 0x04,
27        Downcast = 0x05,
28        Deserialize = 0x06,
29        Custom = 0x07,
30        Io = 0x08,
31    }
32
33    #[derive(Debug, PartialEq, Eq)]
34    #[repr(C)]
35    #[diplomat::rust_link(icu::locale::ParseError, Enum, compact)]
36    #[non_exhaustive]
37    pub enum LocaleParseError {
38        Unknown = 0x00,
39        Language = 0x01,
40        Subtag = 0x02,
41        Extension = 0x03,
42    }
43
44    #[derive(Debug, PartialEq, Eq)]
45    #[repr(C)]
46    #[diplomat::rust_link(fixed_decimal::ParseError, Enum, compact)]
47    #[cfg(any(feature = "decimal", feature = "plurals"))]
48    #[non_exhaustive]
49    pub enum DecimalParseError {
50        Unknown = 0x00,
51        Limit = 0x01,
52        Syntax = 0x02,
53    }
54
55    #[derive(Debug, PartialEq, Eq)]
56    #[diplomat::rust_link(fixed_decimal::LimitError, Struct, compact)]
57    #[cfg(feature = "decimal")]
58    pub struct DecimalLimitError;
59
60    #[derive(Debug, PartialEq, Eq)]
61    #[repr(C)]
62    #[diplomat::rust_link(icu::calendar::RangeError, Struct, compact)]
63    #[diplomat::rust_link(icu::calendar::DateError, Enum, compact)]
64    #[cfg(feature = "calendar")]
65    #[non_exhaustive]
66    pub enum CalendarError {
67        Unknown = 0x00,
68        OutOfRange = 0x01,
69        UnknownEra = 0x02,
70        UnknownMonthCode = 0x03,
71    }
72
73    #[derive(Debug, PartialEq, Eq)]
74    #[repr(C)]
75    #[diplomat::rust_link(icu::calendar::error::DateFromFieldsError, Enum, compact)]
76    #[cfg(all(feature = "unstable", feature = "calendar"))]
77    #[non_exhaustive]
78    pub enum CalendarDateFromFieldsError {
79        Unknown = 0x00,
80        OutOfRange = 0x01,
81        UnknownEra = 0x02,
82        MonthCodeInvalidSyntax = 0x03,
83        MonthCodeNotInCalendar = 0x04,
84        MonthCodeNotInYear = 0x05,
85        InconsistentYear = 0x06,
86        InconsistentMonth = 0x07,
87        NotEnoughFields = 0x08,
88    }
89
90    #[derive(Debug, PartialEq, Eq)]
91    #[repr(C)]
92    #[diplomat::rust_link(icu::calendar::ParseError, Enum, compact)]
93    #[diplomat::rust_link(icu::time::ParseError, Enum, compact)]
94    #[cfg(feature = "calendar")]
95    #[non_exhaustive]
96    pub enum Rfc9557ParseError {
97        Unknown = 0x00,
98        InvalidSyntax = 0x01,
99        OutOfRange = 0x02,
100        MissingFields = 0x03,
101        UnknownCalendar = 0x04,
102    }
103
104    #[derive(Debug, PartialEq, Eq)]
105    #[diplomat::rust_link(icu::time::zone::InvalidOffsetError, Struct, compact)]
106    #[cfg(feature = "datetime")]
107    pub struct TimeZoneInvalidOffsetError;
108
109    #[derive(Debug, PartialEq, Eq)]
110    #[repr(C)]
111    #[diplomat::rust_link(icu::datetime::DateTimeFormatterLoadError, Enum, compact)]
112    #[diplomat::rust_link(icu::datetime::pattern::PatternLoadError, Enum, compact)]
113    #[diplomat::rust_link(icu_provider::DataError, Struct, compact)]
114    #[diplomat::rust_link(icu_provider::DataErrorKind, Enum, compact)]
115    #[non_exhaustive]
116    pub enum DateTimeFormatterLoadError {
117        Unknown = 0x00,
118
119        InvalidDateFields = 0x8_01,
120        UnsupportedLength = 0x8_03,
121        ConflictingField = 0x8_09,
122        FormatterTooSpecific = 0x8_0A,
123
124        DataMarkerNotFound = 0x01,
125        DataIdentifierNotFound = 0x02,
126        DataInvalidRequest = 0x03,
127        DataInconsistentData = 0x04,
128        DataDowncast = 0x05,
129        DataDeserialize = 0x06,
130        DataCustom = 0x07,
131        DataIo = 0x08,
132    }
133
134    #[cfg(feature = "datetime")]
135    #[diplomat::rust_link(icu::datetime::MismatchedCalendarError, Struct)]
136    pub struct DateTimeMismatchedCalendarError {
137        pub this_kind: CalendarKind,
138        pub date_kind: DiplomatOption<CalendarKind>,
139    }
140
141    /// An error when formatting a datetime.
142    ///
143    /// Currently never returned by any API.
144    #[cfg(feature = "datetime")]
145    #[derive(Debug, PartialEq, Eq)]
146    #[repr(C)]
147    #[diplomat::rust_link(
148        icu::datetime::unchecked::FormattedDateTimeUncheckedError,
149        Enum,
150        compact
151    )]
152    #[non_exhaustive]
153    pub enum DateTimeWriteError {
154        Unknown = 0x00,
155        /// Unused
156        MissingTimeZoneVariant = 0x01,
157    }
158}
159
160impl From<icu_provider::DataError> for DataError {
161    fn from(e: icu_provider::DataError) -> Self {
162        match e.kind {
163            icu_provider::DataErrorKind::MarkerNotFound => Self::MarkerNotFound,
164            icu_provider::DataErrorKind::IdentifierNotFound => Self::IdentifierNotFound,
165            icu_provider::DataErrorKind::InvalidRequest => Self::InvalidRequest,
166            icu_provider::DataErrorKind::InconsistentData(..) => Self::InconsistentData,
167            icu_provider::DataErrorKind::Downcast(..) => Self::Downcast,
168            icu_provider::DataErrorKind::Deserialize => Self::Deserialize,
169            icu_provider::DataErrorKind::Custom => Self::Custom,
170            #[cfg(all(
171                feature = "provider_fs",
172                not(any(target_arch = "wasm32", target_os = "none"))
173            ))]
174            icu_provider::DataErrorKind::Io(..) => Self::Io,
175            _ => Self::Unknown,
176        }
177    }
178}
179
180#[cfg(feature = "calendar")]
181impl From<icu_calendar::RangeError> for CalendarError {
182    fn from(_: icu_calendar::RangeError) -> Self {
183        Self::OutOfRange
184    }
185}
186
187#[cfg(feature = "calendar")]
188impl From<icu_calendar::DateError> for CalendarError {
189    fn from(e: icu_calendar::DateError) -> Self {
190        match e {
191            icu_calendar::DateError::Range { .. } => Self::OutOfRange,
192            icu_calendar::DateError::UnknownEra => Self::UnknownEra,
193            icu_calendar::DateError::UnknownMonthCode(..) => Self::UnknownMonthCode,
194            _ => Self::Unknown,
195        }
196    }
197}
198
199#[cfg(feature = "calendar")]
200#[cfg(all(feature = "unstable", feature = "calendar"))]
201impl From<icu_calendar::error::DateFromFieldsError> for CalendarDateFromFieldsError {
202    fn from(e: icu_calendar::error::DateFromFieldsError) -> Self {
203        match e {
204            icu_calendar::error::DateFromFieldsError::Range(_) => Self::OutOfRange,
205            icu_calendar::error::DateFromFieldsError::UnknownEra => Self::UnknownEra,
206            icu_calendar::error::DateFromFieldsError::MonthCodeInvalidSyntax => {
207                Self::MonthCodeInvalidSyntax
208            }
209            icu_calendar::error::DateFromFieldsError::MonthCodeNotInCalendar => {
210                Self::MonthCodeNotInCalendar
211            }
212            icu_calendar::error::DateFromFieldsError::MonthCodeNotInYear => {
213                Self::MonthCodeNotInYear
214            }
215            icu_calendar::error::DateFromFieldsError::InconsistentYear => Self::InconsistentYear,
216            icu_calendar::error::DateFromFieldsError::InconsistentMonth => Self::InconsistentMonth,
217            icu_calendar::error::DateFromFieldsError::NotEnoughFields => Self::NotEnoughFields,
218            _ => Self::Unknown,
219        }
220    }
221}
222
223#[cfg(feature = "calendar")]
224impl From<icu_calendar::ParseError> for Rfc9557ParseError {
225    fn from(e: icu_calendar::ParseError) -> Self {
226        match e {
227            icu_calendar::ParseError::Syntax(_) => Self::InvalidSyntax,
228            icu_calendar::ParseError::MissingFields => Self::MissingFields,
229            icu_calendar::ParseError::Range(_) => Self::OutOfRange,
230            icu_calendar::ParseError::UnknownCalendar => Self::UnknownCalendar,
231            _ => Self::Unknown,
232        }
233    }
234}
235
236#[cfg(feature = "calendar")]
237impl From<icu_time::ParseError> for Rfc9557ParseError {
238    fn from(e: icu_time::ParseError) -> Self {
239        match e {
240            icu_time::ParseError::Syntax(_) => Self::InvalidSyntax,
241            icu_time::ParseError::MissingFields => Self::MissingFields,
242            icu_time::ParseError::Range(_) => Self::OutOfRange,
243            icu_time::ParseError::UnknownCalendar => Self::UnknownCalendar,
244            // TODO
245            _ => Self::Unknown,
246        }
247    }
248}
249
250#[cfg(feature = "datetime")]
251impl From<icu_datetime::DateTimeFormatterLoadError> for DateTimeFormatterLoadError {
252    fn from(e: icu_datetime::DateTimeFormatterLoadError) -> Self {
253        match e {
254            icu_datetime::DateTimeFormatterLoadError::Names(
255                icu_datetime::pattern::PatternLoadError::ConflictingField { .. },
256            ) => Self::ConflictingField,
257            icu_datetime::DateTimeFormatterLoadError::Names(
258                icu_datetime::pattern::PatternLoadError::UnsupportedLength(_),
259            ) => Self::UnsupportedLength,
260            icu_datetime::DateTimeFormatterLoadError::Names(
261                icu_datetime::pattern::PatternLoadError::FormatterTooSpecific(_),
262            ) => Self::FormatterTooSpecific,
263            icu_datetime::DateTimeFormatterLoadError::Names(
264                icu_datetime::pattern::PatternLoadError::Data(data_error, _),
265            ) => data_error.into(),
266            icu_datetime::DateTimeFormatterLoadError::Data(data_error) => data_error.into(),
267            _ => Self::Unknown,
268        }
269    }
270}
271
272#[cfg(feature = "datetime")]
273impl From<icu_provider::DataError> for DateTimeFormatterLoadError {
274    fn from(e: icu_provider::DataError) -> Self {
275        match e.kind {
276            icu_provider::DataErrorKind::MarkerNotFound => Self::DataMarkerNotFound,
277            icu_provider::DataErrorKind::IdentifierNotFound => Self::DataIdentifierNotFound,
278            icu_provider::DataErrorKind::InvalidRequest => Self::DataInvalidRequest,
279            icu_provider::DataErrorKind::InconsistentData(..) => Self::DataInconsistentData,
280            icu_provider::DataErrorKind::Downcast(..) => Self::DataDowncast,
281            icu_provider::DataErrorKind::Deserialize => Self::DataDeserialize,
282            icu_provider::DataErrorKind::Custom => Self::DataCustom,
283            #[cfg(all(
284                feature = "provider_fs",
285                not(any(target_arch = "wasm32", target_os = "none"))
286            ))]
287            icu_provider::DataErrorKind::Io(..) => Self::DataIo,
288            _ => Self::Unknown,
289        }
290    }
291}
292
293#[cfg(feature = "datetime")]
294impl From<icu_datetime::pattern::PatternLoadError> for ffi::DateTimeFormatterLoadError {
295    fn from(value: icu_datetime::pattern::PatternLoadError) -> Self {
296        match value {
297            icu_datetime::pattern::PatternLoadError::ConflictingField { .. } => {
298                Self::ConflictingField
299            }
300            icu_datetime::pattern::PatternLoadError::UnsupportedLength(_) => {
301                Self::UnsupportedLength
302            }
303            icu_datetime::pattern::PatternLoadError::FormatterTooSpecific(_) => {
304                Self::FormatterTooSpecific
305            }
306            icu_datetime::pattern::PatternLoadError::Data(data_error, _) => data_error.into(),
307            _ => Self::Unknown,
308        }
309    }
310}
311
312#[cfg(feature = "datetime")]
313impl From<icu_datetime::MismatchedCalendarError> for ffi::DateTimeMismatchedCalendarError {
314    fn from(value: icu_datetime::MismatchedCalendarError) -> Self {
315        Self {
316            this_kind: value.this_kind.into(),
317            date_kind: value.date_kind.map(Into::into).into(),
318        }
319    }
320}
321
322#[cfg(feature = "datetime")]
323impl From<icu_datetime::unchecked::FormattedDateTimeUncheckedError> for DateTimeWriteError {
324    fn from(err: icu_datetime::unchecked::FormattedDateTimeUncheckedError) -> Self {
325        debug_assert!(false, "unexpected datetime formatting error: {err}");
326        Self::Unknown
327    }
328}
329
330#[cfg(any(feature = "decimal", feature = "plurals"))]
331impl From<fixed_decimal::ParseError> for DecimalParseError {
332    fn from(e: fixed_decimal::ParseError) -> Self {
333        match e {
334            fixed_decimal::ParseError::Limit => Self::Limit,
335            fixed_decimal::ParseError::Syntax => Self::Syntax,
336            _ => Self::Unknown,
337        }
338    }
339}
340
341#[cfg(feature = "decimal")]
342impl From<fixed_decimal::LimitError> for DecimalLimitError {
343    fn from(_: fixed_decimal::LimitError) -> Self {
344        Self
345    }
346}
347
348impl From<icu_locale_core::ParseError> for LocaleParseError {
349    fn from(e: icu_locale_core::ParseError) -> Self {
350        match e {
351            icu_locale_core::ParseError::InvalidLanguage => Self::Language,
352            icu_locale_core::ParseError::InvalidSubtag => Self::Subtag,
353            icu_locale_core::ParseError::InvalidExtension => Self::Extension,
354            icu_locale_core::ParseError::DuplicatedExtension => Self::Extension,
355            _ => Self::Unknown,
356        }
357    }
358}
359
360#[cfg(feature = "datetime")]
361impl From<icu_time::zone::InvalidOffsetError> for TimeZoneInvalidOffsetError {
362    fn from(_: icu_time::zone::InvalidOffsetError) -> Self {
363        Self
364    }
365}