1use core::{fmt, mem};
7use static_assertions::const_assert;
8#[cfg(feature = "std")]
9use std::error;
10
11#[non_exhaustive]
13#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
14pub enum Error {
15 Overflow(usize),
18 Underflow(usize),
20 InvalidDigit(usize),
22 Empty(usize),
24 EmptyMantissa(usize),
26 EmptyExponent(usize),
28 EmptyInteger(usize),
30 EmptyFraction(usize),
32 InvalidPositiveMantissaSign(usize),
34 MissingMantissaSign(usize),
36 InvalidExponent(usize),
38 InvalidPositiveExponentSign(usize),
40 MissingExponentSign(usize),
42 ExponentWithoutFraction(usize),
44 InvalidLeadingZeros(usize),
46 MissingExponent(usize),
48 MissingSign(usize),
50 InvalidPositiveSign(usize),
52 InvalidNegativeSign(usize),
54
55 InvalidMantissaRadix,
58 InvalidExponentBase,
60 InvalidExponentRadix,
62 InvalidDigitSeparator,
64 InvalidDecimalPoint,
66 InvalidExponentSymbol,
68 InvalidBasePrefix,
70 InvalidBaseSuffix,
72 InvalidPunctuation,
74 InvalidExponentFlags,
76 InvalidMantissaSign,
78 InvalidExponentSign,
80 InvalidSpecial,
82 InvalidConsecutiveIntegerDigitSeparator,
84 InvalidConsecutiveFractionDigitSeparator,
86 InvalidConsecutiveExponentDigitSeparator,
88 InvalidFlags,
90
91 InvalidNanString,
94 NanStringTooLong,
96 InvalidInfString,
98 InfStringTooLong,
100 InvalidInfinityString,
102 InfinityStringTooLong,
104 InfinityStringTooShort,
106 InvalidFloatParseAlgorithm,
108 InvalidRadix,
110 InvalidFloatPrecision,
112 InvalidNegativeExponentBreak,
114 InvalidPositiveExponentBreak,
116
117 Success,
120}
121
122const_assert!(mem::size_of::<Error>() <= 2 * mem::size_of::<usize>());
124
125macro_rules! is_error_type {
126 ($name:ident, $type:ident$($t:tt)*) => (
127 pub const fn $name(&self) -> bool {
129 if let Self::$type$($t)* = self {
131 true
132 } else {
133 false
134 }
135 }
136 );
137}
138
139impl Error {
140 pub fn index(&self) -> Option<&usize> {
142 match self {
143 Self::Overflow(index) => Some(index),
145 Self::Underflow(index) => Some(index),
146 Self::InvalidDigit(index) => Some(index),
147 Self::Empty(index) => Some(index),
148 Self::EmptyMantissa(index) => Some(index),
149 Self::EmptyExponent(index) => Some(index),
150 Self::EmptyInteger(index) => Some(index),
151 Self::EmptyFraction(index) => Some(index),
152 Self::InvalidPositiveMantissaSign(index) => Some(index),
153 Self::MissingMantissaSign(index) => Some(index),
154 Self::InvalidExponent(index) => Some(index),
155 Self::InvalidPositiveExponentSign(index) => Some(index),
156 Self::MissingExponentSign(index) => Some(index),
157 Self::ExponentWithoutFraction(index) => Some(index),
158 Self::InvalidLeadingZeros(index) => Some(index),
159 Self::MissingExponent(index) => Some(index),
160 Self::MissingSign(index) => Some(index),
161 Self::InvalidPositiveSign(index) => Some(index),
162 Self::InvalidNegativeSign(index) => Some(index),
163
164 Self::InvalidMantissaRadix => None,
166 Self::InvalidExponentBase => None,
167 Self::InvalidExponentRadix => None,
168 Self::InvalidDigitSeparator => None,
169 Self::InvalidDecimalPoint => None,
170 Self::InvalidExponentSymbol => None,
171 Self::InvalidBasePrefix => None,
172 Self::InvalidBaseSuffix => None,
173 Self::InvalidPunctuation => None,
174 Self::InvalidExponentFlags => None,
175 Self::InvalidMantissaSign => None,
176 Self::InvalidExponentSign => None,
177 Self::InvalidSpecial => None,
178 Self::InvalidConsecutiveIntegerDigitSeparator => None,
179 Self::InvalidConsecutiveFractionDigitSeparator => None,
180 Self::InvalidConsecutiveExponentDigitSeparator => None,
181 Self::InvalidFlags => None,
182
183 Self::InvalidNanString => None,
185 Self::NanStringTooLong => None,
186 Self::InvalidInfString => None,
187 Self::InfStringTooLong => None,
188 Self::InvalidInfinityString => None,
189 Self::InfinityStringTooLong => None,
190 Self::InfinityStringTooShort => None,
191 Self::InvalidFloatParseAlgorithm => None,
192 Self::InvalidRadix => None,
193 Self::InvalidFloatPrecision => None,
194 Self::InvalidNegativeExponentBreak => None,
195 Self::InvalidPositiveExponentBreak => None,
196
197 Self::Success => None,
199 }
200 }
201
202 is_error_type!(is_overflow, Overflow(_));
203 is_error_type!(is_underflow, Underflow(_));
204 is_error_type!(is_invalid_digit, InvalidDigit(_));
205 is_error_type!(is_empty, Empty(_));
206 is_error_type!(is_empty_mantissa, EmptyMantissa(_));
207 is_error_type!(is_empty_exponent, EmptyExponent(_));
208 is_error_type!(is_empty_integer, EmptyInteger(_));
209 is_error_type!(is_empty_fraction, EmptyFraction(_));
210 is_error_type!(is_invalid_positive_mantissa_sign, InvalidPositiveMantissaSign(_));
211 is_error_type!(is_missing_mantissa_sign, MissingMantissaSign(_));
212 is_error_type!(is_invalid_exponent, InvalidExponent(_));
213 is_error_type!(is_invalid_positive_exponent_sign, InvalidPositiveExponentSign(_));
214 is_error_type!(is_missing_exponent_sign, MissingExponentSign(_));
215 is_error_type!(is_exponent_without_fraction, ExponentWithoutFraction(_));
216 is_error_type!(is_invalid_leading_zeros, InvalidLeadingZeros(_));
217 is_error_type!(is_missing_exponent, MissingExponent(_));
218 is_error_type!(is_missing_sign, MissingSign(_));
219 is_error_type!(is_invalid_positive_sign, InvalidPositiveSign(_));
220 is_error_type!(is_invalid_negative_sign, InvalidNegativeSign(_));
221 is_error_type!(is_invalid_mantissa_radix, InvalidMantissaRadix);
222 is_error_type!(is_invalid_exponent_base, InvalidExponentBase);
223 is_error_type!(is_invalid_exponent_radix, InvalidExponentRadix);
224 is_error_type!(is_invalid_digit_separator, InvalidDigitSeparator);
225 is_error_type!(is_invalid_decimal_point, InvalidDecimalPoint);
226 is_error_type!(is_invalid_exponent_symbol, InvalidExponentSymbol);
227 is_error_type!(is_invalid_base_prefix, InvalidBasePrefix);
228 is_error_type!(is_invalid_base_suffix, InvalidBaseSuffix);
229 is_error_type!(is_invalid_punctuation, InvalidPunctuation);
230 is_error_type!(is_invalid_exponent_flags, InvalidExponentFlags);
231 is_error_type!(is_invalid_mantissa_sign, InvalidMantissaSign);
232 is_error_type!(is_invalid_exponent_sign, InvalidExponentSign);
233 is_error_type!(is_invalid_special, InvalidSpecial);
234 is_error_type!(
235 is_invalid_consecutive_integer_digit_separator,
236 InvalidConsecutiveIntegerDigitSeparator
237 );
238 is_error_type!(
239 is_invalid_consecutive_fraction_digit_separator,
240 InvalidConsecutiveFractionDigitSeparator
241 );
242 is_error_type!(
243 is_invalid_consecutive_exponent_digit_separator,
244 InvalidConsecutiveExponentDigitSeparator
245 );
246 is_error_type!(is_invalid_flags, InvalidFlags);
247 is_error_type!(is_invalid_nan_string, InvalidNanString);
248 is_error_type!(is_nan_string_too_long, NanStringTooLong);
249 is_error_type!(is_invalid_inf_string, InvalidInfString);
250 is_error_type!(is_inf_string_too_long, InfStringTooLong);
251 is_error_type!(is_invalid_infinity_string, InvalidInfinityString);
252 is_error_type!(is_infinity_string_too_long, InfinityStringTooLong);
253 is_error_type!(is_infinity_string_too_short, InfinityStringTooShort);
254 is_error_type!(is_invalid_float_parse_algorithm, InvalidFloatParseAlgorithm);
255 is_error_type!(is_invalid_radix, InvalidRadix);
256 is_error_type!(is_invalid_float_precision, InvalidFloatPrecision);
257 is_error_type!(is_invalid_negative_exponent_break, InvalidNegativeExponentBreak);
258 is_error_type!(is_invalid_positive_exponent_break, InvalidPositiveExponentBreak);
259 is_error_type!(is_success, Success);
260}
261
262macro_rules! write_parse_error {
264 ($formatter:ident, $message:literal, $index:ident) => {
265 write!($formatter, "lexical parse error: {} at index {}", $message, $index)
266 };
267}
268
269macro_rules! format_message {
271 ($formatter:ident, $message:literal) => {
272 write!($formatter, "lexical number format error: {}", $message)
273 };
274}
275
276macro_rules! options_message {
278 ($formatter:ident, $message:literal) => {
279 write!($formatter, "lexical options error: {}", $message)
280 };
281}
282
283impl fmt::Display for Error {
284 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
285 match self {
286 Self::Overflow(index) => write_parse_error!(formatter, "'numeric overflow occurred'", index),
288 Self::Underflow(index) => write_parse_error!(formatter, "'numeric underflow occurred'", index),
289 Self::InvalidDigit(index) => write_parse_error!(formatter, "'invalid digit found'", index),
290 Self::Empty(index) => write_parse_error!(formatter, "'the string to parse was empty'", index),
291 Self::EmptyMantissa(index) => write_parse_error!(formatter, "'no significant digits found'", index),
292 Self::EmptyExponent(index) => write_parse_error!(formatter, "'exponent notation found without an exponent'", index),
293 Self::EmptyInteger(index) => write_parse_error!(formatter, "'invalid float with no integer digits'", index),
294 Self::EmptyFraction(index) => write_parse_error!(formatter, "'invalid float with no fraction digits'", index),
295 Self::InvalidPositiveMantissaSign(index) => write_parse_error!(formatter, "'invalid `+` sign before significant digits'", index),
296 Self::MissingMantissaSign(index) => write_parse_error!(formatter, "'missing required `+/-` sign for significant digits'", index),
297 Self::InvalidExponent(index) => write_parse_error!(formatter, "'exponent found but not allowed'", index),
298 Self::InvalidPositiveExponentSign(index) => write_parse_error!(formatter, "'invalid `+` sign in exponent'", index),
299 Self::MissingExponentSign(index) => write_parse_error!(formatter, "'missing required `+/-` sign for exponent'", index),
300 Self::ExponentWithoutFraction(index) => write_parse_error!(formatter, "'invalid float containing exponent without fraction'", index),
301 Self::InvalidLeadingZeros(index) => write_parse_error!(formatter, "'invalid number with leading zeros before digits'", index),
302 Self::MissingExponent(index) => write_parse_error!(formatter, "'missing required exponent'", index),
303 Self::MissingSign(index) => write_parse_error!(formatter, "'missing required `+/-` sign for integer'", index),
304 Self::InvalidPositiveSign(index) => write_parse_error!(formatter, "'invalid `+` sign for an integer was found'", index),
305 Self::InvalidNegativeSign(index) => write_parse_error!(formatter, "'invalid `-` sign for an unsigned type was found'", index),
306
307 Self::InvalidMantissaRadix => format_message!(formatter, "'invalid radix for mantissa digits'"),
309 Self::InvalidExponentBase => format_message!(formatter, "'invalid exponent base'"),
310 Self::InvalidExponentRadix => format_message!(formatter, "'invalid radix for exponent digits'"),
311 Self::InvalidDigitSeparator => format_message!(formatter, "'invalid digit separator: must be ASCII and not a digit or a `+/-` sign'"),
312 Self::InvalidDecimalPoint => format_message!(formatter, "'invalid decimal point: must be ASCII and not a digit or a `+/-` sign'"),
313 Self::InvalidExponentSymbol => format_message!(formatter, "'invalid exponent symbol: must be ASCII and not a digit or a `+/-` sign'"),
314 Self::InvalidBasePrefix => format_message!(formatter, "'invalid base prefix character'"),
315 Self::InvalidBaseSuffix => format_message!(formatter, "'invalid base suffix character'"),
316 Self::InvalidPunctuation => format_message!(formatter, "'invalid punctuation: multiple characters overlap'"),
317 Self::InvalidExponentFlags => format_message!(formatter, "'exponent flags set while disabling exponent notation'"),
318 Self::InvalidMantissaSign => format_message!(formatter, "'disabled the `+` sign while requiring a sign for significant digits'"),
319 Self::InvalidExponentSign => format_message!(formatter, "'disabled the `+` sign while requiring a sign for exponent digits'"),
320 Self::InvalidSpecial => format_message!(formatter, "'special flags set while disabling special floats'"),
321 Self::InvalidConsecutiveIntegerDigitSeparator => format_message!(formatter, "'enabled consecutive digit separators in the integer without setting a valid location'"),
322 Self::InvalidConsecutiveFractionDigitSeparator => format_message!(formatter, "'enabled consecutive digit separators in the fraction without setting a valid location'"),
323 Self::InvalidConsecutiveExponentDigitSeparator => format_message!(formatter, "'enabled consecutive digit separators in the exponent without setting a valid location'"),
324 Self::InvalidFlags => format_message!(formatter, "'invalid flags enabled without the format feature'"),
325
326 Self::InvalidNanString => options_message!(formatter, "'NaN string must started with `n`'"),
328 Self::NanStringTooLong => options_message!(formatter, "'NaN string is too long'"),
329 Self::InvalidInfString => options_message!(formatter, "'short infinity string must started with `i`'"),
330 Self::InfStringTooLong => options_message!(formatter, "'short infinity string is too long'"),
331 Self::InvalidInfinityString => options_message!(formatter, "'long infinity string must started with `i`'"),
332 Self::InfinityStringTooLong => options_message!(formatter, "'long infinity string is too long'"),
333 Self::InfinityStringTooShort => options_message!(formatter, "'long infinity string is too short'"),
334 Self::InvalidFloatParseAlgorithm => options_message!(formatter, "'invalid combination of float parse algorithms'"),
335 Self::InvalidRadix => options_message!(formatter, "'invalid radix for significant digits'"),
336 Self::InvalidFloatPrecision => options_message!(formatter, "'invalid float precision: min digits is larger than max digits'"),
337 Self::InvalidNegativeExponentBreak => options_message!(formatter, "'invalid negative exponent break: value is above 0'"),
338 Self::InvalidPositiveExponentBreak => options_message!(formatter, "'invalid positive exponent break: value is below 0'"),
339
340 Self::Success => write!(formatter, "'not actually an error'"),
342 }
343 }
344}
345
346#[cfg(feature = "std")]
347impl error::Error for Error {
348}