1 //! C-compatible error type. 2 3 use crate::lib::fmt::{self, Display, Formatter}; 4 5 #[cfg(feature = "std")] 6 use std::error::Error as StdError; 7 8 /// Error code, indicating failure type. 9 /// 10 /// Error messages are designating by an error code of less than 0. 11 /// This is to be compatible with C conventions. This enumeration is 12 /// FFI-compatible for interfacing with C code. 13 /// 14 /// # FFI 15 /// 16 /// For interfacing with FFI-code, this may be approximated by: 17 /// ```text 18 /// const int32_t OVERFLOW = -1; 19 /// const int32_t UNDERFLOW = -2; 20 /// const int32_t INVALID_DIGIT = -3; 21 /// const int32_t EMPTY = -4; 22 /// const int32_t EMPTY_FRACTION = -5; 23 /// const int32_t EMPTY_EXPONENT = -6; 24 /// ``` 25 /// 26 /// # Safety 27 /// 28 /// Assigning any value outside the range `[-6, -1]` to value of type 29 /// ErrorCode may invoke undefined-behavior. 30 #[repr(i32)] 31 #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] 32 pub enum ErrorCode { 33 /// Integral overflow occurred during numeric parsing. 34 /// 35 /// Numeric overflow takes precedence over the presence of an invalid 36 /// digit. 37 Overflow = -1, 38 /// Integral underflow occurred during numeric parsing. 39 /// 40 /// Numeric overflow takes precedence over the presence of an invalid 41 /// digit. 42 Underflow = -2, 43 /// Invalid digit found before string termination. 44 InvalidDigit = -3, 45 /// Empty byte array found. 46 Empty = -4, 47 /// Empty mantissa found. 48 EmptyMantissa = -5, 49 /// Empty exponent found. 50 EmptyExponent = -6, 51 /// Empty integer found. 52 EmptyInteger = -7, 53 /// Empty fraction found. 54 EmptyFraction = -8, 55 /// Invalid positive mantissa sign was found. 56 InvalidPositiveMantissaSign = -9, 57 /// Mantissa sign was required, but not found. 58 MissingMantissaSign = -10, 59 /// Exponent was present but not allowed. 60 InvalidExponent = -11, 61 /// Invalid positive exponent sign was found. 62 InvalidPositiveExponentSign = -12, 63 /// Exponent sign was required, but not found. 64 MissingExponentSign = -13, 65 /// Exponent was present without fraction component. 66 ExponentWithoutFraction = -14, 67 /// Integer had invalid leading zeros. 68 InvalidLeadingZeros = -15, 69 70 // We may add additional variants later, so ensure that client matching 71 // does not depend on exhaustive matching. 72 #[doc(hidden)] 73 __Nonexhaustive = -200, 74 } 75 76 /// Error type for lexical parsing. 77 /// 78 /// This error is FFI-compatible for interfacing with C code. 79 #[repr(C)] 80 #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] 81 pub struct Error { 82 /// Error code designating the type of error occurred. 83 pub code: ErrorCode, 84 /// Optional position within the buffer for the error. 85 pub index: usize, 86 } 87 88 impl From<ErrorCode> for Error { 89 #[inline] from(code: ErrorCode) -> Self90 fn from(code: ErrorCode) -> Self { 91 Error { code: code, index: 0 } 92 } 93 } 94 95 impl From<(ErrorCode, usize)> for Error { 96 #[inline] from(error: (ErrorCode, usize)) -> Self97 fn from(error: (ErrorCode, usize)) -> Self { 98 Error { code: error.0, index: error.1 } 99 } 100 } 101 102 impl Display for Error { fmt(&self, f: &mut Formatter<'_>) -> fmt::Result103 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 104 write!(f, "lexical error: {:?} at index {}.", self.code, self.index) 105 } 106 } 107 108 #[cfg(feature = "std")] 109 impl StdError for Error {} 110