Skip to main content

mf2_locale_data/
error.rs

1//! Errors of the build-side locale data.
2
3use thiserror::Error;
4
5/// A syntax error in one `pluralRule-count-*` string.
6#[derive(Debug, Error, PartialEq, Eq)]
7#[non_exhaustive]
8pub enum ParseError {
9    /// A character the rule grammar does not allow here.
10    #[error("unexpected character {ch:?} at byte {at}")]
11    UnexpectedChar {
12        /// Its byte offset.
13        at: usize,
14        /// The character.
15        ch: char,
16    },
17    /// Something else was expected.
18    #[error("expected {expected} at byte {at}")]
19    Expected {
20        /// The byte offset.
21        at: usize,
22        /// What the grammar expected.
23        expected: &'static str,
24    },
25    /// A number does not fit.
26    #[error("number too large at byte {at}")]
27    Overflow {
28        /// Its byte offset.
29        at: usize,
30    },
31    /// A range whose low end is above its high end.
32    #[error("range {lo}..{hi} is empty")]
33    EmptyRange {
34        /// The low end.
35        lo: u64,
36        /// The high end.
37        hi: u64,
38    },
39    /// `n % 0`.
40    #[error("modulus 0")]
41    ZeroModulus,
42    /// The `other` category has a condition.
43    #[error("the `other` rule must have no condition")]
44    OtherWithCondition,
45    /// A category other than `other` has none.
46    #[error("a non-`other` rule has no condition")]
47    MissingCondition,
48    /// Not one of CLDR's plural categories.
49    #[error("unknown category {0:?}")]
50    UnknownCategory(String),
51    /// More OR groups than the encoding holds.
52    #[error("more than 31 OR groups in one rule")]
53    TooManyGroups,
54    /// A value beyond the operand contract.
55    #[error("a modulus or value ≥ 10^18 (plans/02-catalog-format.md §4.1 operand contract)")]
56    TooLarge,
57    /// A malformed `@integer` / `@decimal` sample.
58    #[error("bad sample {0:?}")]
59    Sample(String),
60    /// A sample range whose ends cannot be compared.
61    #[error("sample range {0:?}: endpoints differ in fraction digits or use an exponent")]
62    SampleRange(String),
63}
64
65/// A problem with the shipped rule table or the CLDR input.
66#[derive(Debug, Error)]
67#[non_exhaustive]
68pub enum Error {
69    /// A plural rule does not parse.
70    #[error("{0}")]
71    Parse(#[from] ParseError),
72    /// A plural rule of the shipped table does not parse.
73    #[error("{kind} {locale} {category}: {source}")]
74    Rule {
75        /// `cardinal` or `ordinal`.
76        kind: &'static str,
77        /// The locale.
78        locale: String,
79        /// The plural category.
80        category: String,
81        /// Why.
82        #[source]
83        source: ParseError,
84    },
85    /// A line of a shipped table is malformed.
86    #[error("table line {line}: {message}")]
87    Table {
88        /// One-based line.
89        line: usize,
90        /// What is wrong.
91        message: String,
92    },
93    /// A CLDR number pattern the encoder does not accept.
94    #[error("CLDR number pattern {pattern:?}: {message}")]
95    Pattern {
96        /// The pattern.
97        pattern: String,
98        /// What is wrong.
99        message: &'static str,
100    },
101    /// A locale's number data lacks a field.
102    #[error("number data of {locale} ({system}): no {field}")]
103    Missing {
104        /// The locale.
105        locale: String,
106        /// The numbering system.
107        system: String,
108        /// The missing field.
109        field: &'static str,
110    },
111    /// The catalog writer refused a LOCALE entry.
112    #[error("LOCALE entry: {0}")]
113    Entry(#[from] mf2_catalog::WriteError),
114    /// The CLDR JSON does not parse (`extract`).
115    #[cfg(feature = "extract")]
116    #[error("CLDR JSON: {0}")]
117    Json(#[from] serde_json::Error),
118    /// The CLDR JSON is not shaped as expected (`extract`).
119    #[cfg(feature = "extract")]
120    #[error("unexpected CLDR JSON shape: {0}")]
121    Shape(String),
122    /// The CLDR input breaks an assumption the table format rests on (the
123    /// extractor checks each one, so a CLDR update that changes them is
124    /// noticed, not silently mis-encoded).
125    #[cfg(feature = "extract")]
126    #[error("CLDR data: {0}")]
127    Assumption(String),
128    /// A file could not be read or written (`extract`).
129    #[cfg(feature = "extract")]
130    #[error("{path}: {source}")]
131    Io {
132        /// The file.
133        path: std::path::PathBuf,
134        /// What the operating system said.
135        #[source]
136        source: std::io::Error,
137    },
138    /// ICU4X data for `icu.blob` (`icu-blob`).
139    #[cfg(feature = "icu-blob")]
140    #[error("icu.blob: {0}")]
141    IcuData(#[from] icu_provider::DataError),
142    /// Some formatter of the `datetime-icu` backend does not build from
143    /// ICU4X's data for the locale (`icu-blob`).
144    #[cfg(feature = "icu-blob")]
145    #[error("icu.blob for {locale}: {count} formatter(s) do not build, e.g. {first}")]
146    IcuBlobBuild {
147        /// The locale.
148        locale: String,
149        /// How many formatters fail.
150        count: usize,
151        /// The first that does.
152        first: String,
153    },
154}