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}