1use core::{fmt, mem};
7#[cfg(feature = "std")]
8use std::error;
9
10use static_assertions::const_assert;
11
12#[non_exhaustive]
14#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
15pub enum Error {
16 Overflow(usize),
19 Underflow(usize),
21 InvalidDigit(usize),
23 Empty(usize),
25 EmptyMantissa(usize),
27 EmptyExponent(usize),
29 EmptyInteger(usize),
31 EmptyFraction(usize),
33 InvalidPositiveMantissaSign(usize),
35 MissingMantissaSign(usize),
37 InvalidExponent(usize),
39 InvalidPositiveExponentSign(usize),
41 MissingExponentSign(usize),
43 ExponentWithoutFraction(usize),
45 InvalidLeadingZeros(usize),
47 MissingExponent(usize),
49 MissingSign(usize),
51 InvalidPositiveSign(usize),
53 InvalidNegativeSign(usize),
55
56 InvalidMantissaRadix,
59 InvalidExponentBase,
61 InvalidExponentRadix,
63 InvalidDigitSeparator,
65 InvalidDecimalPoint,
67 InvalidExponentSymbol,
69 InvalidBasePrefix,
71 InvalidBaseSuffix,
73 InvalidPunctuation,
75 InvalidExponentFlags,
77 InvalidMantissaSign,
79 InvalidExponentSign,
81 InvalidSpecial,
83 InvalidConsecutiveIntegerDigitSeparator,
85 InvalidConsecutiveFractionDigitSeparator,
87 InvalidConsecutiveExponentDigitSeparator,
89 InvalidFlags,
91
92 InvalidNanString,
95 NanStringTooLong,
97 InvalidInfString,
99 InfStringTooLong,
101 InvalidInfinityString,
103 InfinityStringTooLong,
105 InfinityStringTooShort,
107 InvalidFloatParseAlgorithm,
109 InvalidRadix,
111 InvalidFloatPrecision,
113 InvalidNegativeExponentBreak,
115 InvalidPositiveExponentBreak,
117
118 Success,
121}
122
123const_assert!(mem::size_of::<Error>() <= 2 * mem::size_of::<usize>());
125
126macro_rules! is_error_type {
127 ($name:ident, $type:ident$($t:tt)*) => (
128 pub const fn $name(&self) -> bool {
130 if let Self::$type$($t)* = self {
132 true
133 } else {
134 false
135 }
136 }
137 );
138}
139
140impl Error {
141 pub fn index(&self) -> Option<&usize> {
143 match self {
144 Self::Overflow(index) => Some(index),
146 Self::Underflow(index) => Some(index),
147 Self::InvalidDigit(index) => Some(index),
148 Self::Empty(index) => Some(index),
149 Self::EmptyMantissa(index) => Some(index),
150 Self::EmptyExponent(index) => Some(index),
151 Self::EmptyInteger(index) => Some(index),
152 Self::EmptyFraction(index) => Some(index),
153 Self::InvalidPositiveMantissaSign(index) => Some(index),
154 Self::MissingMantissaSign(index) => Some(index),
155 Self::InvalidExponent(index) => Some(index),
156 Self::InvalidPositiveExponentSign(index) => Some(index),
157 Self::MissingExponentSign(index) => Some(index),
158 Self::ExponentWithoutFraction(index) => Some(index),
159 Self::InvalidLeadingZeros(index) => Some(index),
160 Self::MissingExponent(index) => Some(index),
161 Self::MissingSign(index) => Some(index),
162 Self::InvalidPositiveSign(index) => Some(index),
163 Self::InvalidNegativeSign(index) => Some(index),
164
165 Self::InvalidMantissaRadix => None,
167 Self::InvalidExponentBase => None,
168 Self::InvalidExponentRadix => None,
169 Self::InvalidDigitSeparator => None,
170 Self::InvalidDecimalPoint => None,
171 Self::InvalidExponentSymbol => None,
172 Self::InvalidBasePrefix => None,
173 Self::InvalidBaseSuffix => None,
174 Self::InvalidPunctuation => None,
175 Self::InvalidExponentFlags => None,
176 Self::InvalidMantissaSign => None,
177 Self::InvalidExponentSign => None,
178 Self::InvalidSpecial => None,
179 Self::InvalidConsecutiveIntegerDigitSeparator => None,
180 Self::InvalidConsecutiveFractionDigitSeparator => None,
181 Self::InvalidConsecutiveExponentDigitSeparator => None,
182 Self::InvalidFlags => None,
183
184 Self::InvalidNanString => None,
186 Self::NanStringTooLong => None,
187 Self::InvalidInfString => None,
188 Self::InfStringTooLong => None,
189 Self::InvalidInfinityString => None,
190 Self::InfinityStringTooLong => None,
191 Self::InfinityStringTooShort => None,
192 Self::InvalidFloatParseAlgorithm => None,
193 Self::InvalidRadix => None,
194 Self::InvalidFloatPrecision => None,
195 Self::InvalidNegativeExponentBreak => None,
196 Self::InvalidPositiveExponentBreak => None,
197
198 Self::Success => None,
200 }
201 }
202
203 is_error_type!(is_overflow, Overflow(_));
204 is_error_type!(is_underflow, Underflow(_));
205 is_error_type!(is_invalid_digit, InvalidDigit(_));
206 is_error_type!(is_empty, Empty(_));
207 is_error_type!(is_empty_mantissa, EmptyMantissa(_));
208 is_error_type!(is_empty_exponent, EmptyExponent(_));
209 is_error_type!(is_empty_integer, EmptyInteger(_));
210 is_error_type!(is_empty_fraction, EmptyFraction(_));
211 is_error_type!(is_invalid_positive_mantissa_sign, InvalidPositiveMantissaSign(_));
212 is_error_type!(is_missing_mantissa_sign, MissingMantissaSign(_));
213 is_error_type!(is_invalid_exponent, InvalidExponent(_));
214 is_error_type!(is_invalid_positive_exponent_sign, InvalidPositiveExponentSign(_));
215 is_error_type!(is_missing_exponent_sign, MissingExponentSign(_));
216 is_error_type!(is_exponent_without_fraction, ExponentWithoutFraction(_));
217 is_error_type!(is_invalid_leading_zeros, InvalidLeadingZeros(_));
218 is_error_type!(is_missing_exponent, MissingExponent(_));
219 is_error_type!(is_missing_sign, MissingSign(_));
220 is_error_type!(is_invalid_positive_sign, InvalidPositiveSign(_));
221 is_error_type!(is_invalid_negative_sign, InvalidNegativeSign(_));
222 is_error_type!(is_invalid_mantissa_radix, InvalidMantissaRadix);
223 is_error_type!(is_invalid_exponent_base, InvalidExponentBase);
224 is_error_type!(is_invalid_exponent_radix, InvalidExponentRadix);
225 is_error_type!(is_invalid_digit_separator, InvalidDigitSeparator);
226 is_error_type!(is_invalid_decimal_point, InvalidDecimalPoint);
227 is_error_type!(is_invalid_exponent_symbol, InvalidExponentSymbol);
228 is_error_type!(is_invalid_base_prefix, InvalidBasePrefix);
229 is_error_type!(is_invalid_base_suffix, InvalidBaseSuffix);
230 is_error_type!(is_invalid_punctuation, InvalidPunctuation);
231 is_error_type!(is_invalid_exponent_flags, InvalidExponentFlags);
232 is_error_type!(is_invalid_mantissa_sign, InvalidMantissaSign);
233 is_error_type!(is_invalid_exponent_sign, InvalidExponentSign);
234 is_error_type!(is_invalid_special, InvalidSpecial);
235 is_error_type!(
236 is_invalid_consecutive_integer_digit_separator,
237 InvalidConsecutiveIntegerDigitSeparator
238 );
239 is_error_type!(
240 is_invalid_consecutive_fraction_digit_separator,
241 InvalidConsecutiveFractionDigitSeparator
242 );
243 is_error_type!(
244 is_invalid_consecutive_exponent_digit_separator,
245 InvalidConsecutiveExponentDigitSeparator
246 );
247 is_error_type!(is_invalid_flags, InvalidFlags);
248 is_error_type!(is_invalid_nan_string, InvalidNanString);
249 is_error_type!(is_nan_string_too_long, NanStringTooLong);
250 is_error_type!(is_invalid_inf_string, InvalidInfString);
251 is_error_type!(is_inf_string_too_long, InfStringTooLong);
252 is_error_type!(is_invalid_infinity_string, InvalidInfinityString);
253 is_error_type!(is_infinity_string_too_long, InfinityStringTooLong);
254 is_error_type!(is_infinity_string_too_short, InfinityStringTooShort);
255 is_error_type!(is_invalid_float_parse_algorithm, InvalidFloatParseAlgorithm);
256 is_error_type!(is_invalid_radix, InvalidRadix);
257 is_error_type!(is_invalid_float_precision, InvalidFloatPrecision);
258 is_error_type!(is_invalid_negative_exponent_break, InvalidNegativeExponentBreak);
259 is_error_type!(is_invalid_positive_exponent_break, InvalidPositiveExponentBreak);
260 is_error_type!(is_success, Success);
261}
262
263macro_rules! write_parse_error {
265 ($formatter:ident, $message:literal, $index:ident) => {
266 write!($formatter, "lexical parse error: {} at index {}", $message, $index)
267 };
268}
269
270macro_rules! format_message {
272 ($formatter:ident, $message:literal) => {
273 write!($formatter, "lexical number format error: {}", $message)
274 };
275}
276
277macro_rules! options_message {
279 ($formatter:ident, $message:literal) => {
280 write!($formatter, "lexical options error: {}", $message)
281 };
282}
283
284impl fmt::Display for Error {
285 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
286 match self {
287 Self::Overflow(index) => write_parse_error!(formatter, "'numeric overflow occurred'", index),
289 Self::Underflow(index) => write_parse_error!(formatter, "'numeric underflow occurred'", index),
290 Self::InvalidDigit(index) => write_parse_error!(formatter, "'invalid digit found'", index),
291 Self::Empty(index) => write_parse_error!(formatter, "'the string to parse was empty'", index),
292 Self::EmptyMantissa(index) => write_parse_error!(formatter, "'no significant digits found'", index),
293 Self::EmptyExponent(index) => write_parse_error!(formatter, "'exponent notation found without an exponent'", index),
294 Self::EmptyInteger(index) => write_parse_error!(formatter, "'invalid float with no integer digits'", index),
295 Self::EmptyFraction(index) => write_parse_error!(formatter, "'invalid float with no fraction digits'", index),
296 Self::InvalidPositiveMantissaSign(index) => write_parse_error!(formatter, "'invalid `+` sign before significant digits'", index),
297 Self::MissingMantissaSign(index) => write_parse_error!(formatter, "'missing required `+/-` sign for significant digits'", index),
298 Self::InvalidExponent(index) => write_parse_error!(formatter, "'exponent found but not allowed'", index),
299 Self::InvalidPositiveExponentSign(index) => write_parse_error!(formatter, "'invalid `+` sign in exponent'", index),
300 Self::MissingExponentSign(index) => write_parse_error!(formatter, "'missing required `+/-` sign for exponent'", index),
301 Self::ExponentWithoutFraction(index) => write_parse_error!(formatter, "'invalid float containing exponent without fraction'", index),
302 Self::InvalidLeadingZeros(index) => write_parse_error!(formatter, "'invalid number with leading zeros before digits'", index),
303 Self::MissingExponent(index) => write_parse_error!(formatter, "'missing required exponent'", index),
304 Self::MissingSign(index) => write_parse_error!(formatter, "'missing required `+/-` sign for integer'", index),
305 Self::InvalidPositiveSign(index) => write_parse_error!(formatter, "'invalid `+` sign for an integer was found'", index),
306 Self::InvalidNegativeSign(index) => write_parse_error!(formatter, "'invalid `-` sign for an unsigned type was found'", index),
307
308 Self::InvalidMantissaRadix => format_message!(formatter, "'invalid radix for mantissa digits'"),
310 Self::InvalidExponentBase => format_message!(formatter, "'invalid exponent base'"),
311 Self::InvalidExponentRadix => format_message!(formatter, "'invalid radix for exponent digits'"),
312 Self::InvalidDigitSeparator => format_message!(formatter, "'invalid digit separator: must be ASCII and not a digit or a `+/-` sign'"),
313 Self::InvalidDecimalPoint => format_message!(formatter, "'invalid decimal point: must be ASCII and not a digit or a `+/-` sign'"),
314 Self::InvalidExponentSymbol => format_message!(formatter, "'invalid exponent symbol: must be ASCII and not a digit or a `+/-` sign'"),
315 Self::InvalidBasePrefix => format_message!(formatter, "'invalid base prefix character'"),
316 Self::InvalidBaseSuffix => format_message!(formatter, "'invalid base suffix character'"),
317 Self::InvalidPunctuation => format_message!(formatter, "'invalid punctuation: multiple characters overlap'"),
318 Self::InvalidExponentFlags => format_message!(formatter, "'exponent flags set while disabling exponent notation'"),
319 Self::InvalidMantissaSign => format_message!(formatter, "'disabled the `+` sign while requiring a sign for significant digits'"),
320 Self::InvalidExponentSign => format_message!(formatter, "'disabled the `+` sign while requiring a sign for exponent digits'"),
321 Self::InvalidSpecial => format_message!(formatter, "'special flags set while disabling special floats'"),
322 Self::InvalidConsecutiveIntegerDigitSeparator => format_message!(formatter, "'enabled consecutive digit separators in the integer without setting a valid location'"),
323 Self::InvalidConsecutiveFractionDigitSeparator => format_message!(formatter, "'enabled consecutive digit separators in the fraction without setting a valid location'"),
324 Self::InvalidConsecutiveExponentDigitSeparator => format_message!(formatter, "'enabled consecutive digit separators in the exponent without setting a valid location'"),
325 Self::InvalidFlags => format_message!(formatter, "'invalid flags enabled without the format feature'"),
326
327 Self::InvalidNanString => options_message!(formatter, "'NaN string must started with `n`'"),
329 Self::NanStringTooLong => options_message!(formatter, "'NaN string is too long'"),
330 Self::InvalidInfString => options_message!(formatter, "'short infinity string must started with `i`'"),
331 Self::InfStringTooLong => options_message!(formatter, "'short infinity string is too long'"),
332 Self::InvalidInfinityString => options_message!(formatter, "'long infinity string must started with `i`'"),
333 Self::InfinityStringTooLong => options_message!(formatter, "'long infinity string is too long'"),
334 Self::InfinityStringTooShort => options_message!(formatter, "'long infinity string is too short'"),
335 Self::InvalidFloatParseAlgorithm => options_message!(formatter, "'invalid combination of float parse algorithms'"),
336 Self::InvalidRadix => options_message!(formatter, "'invalid radix for significant digits'"),
337 Self::InvalidFloatPrecision => options_message!(formatter, "'invalid float precision: min digits is larger than max digits'"),
338 Self::InvalidNegativeExponentBreak => options_message!(formatter, "'invalid negative exponent break: value is above 0'"),
339 Self::InvalidPositiveExponentBreak => options_message!(formatter, "'invalid positive exponent break: value is below 0'"),
340
341 Self::Success => write!(formatter, "'not actually an error'"),
343 }
344 }
345}
346
347#[cfg(feature = "std")]
348impl error::Error for Error {
349}