use core::{
fmt,
fmt::{Debug, Display, Formatter},
num::{IntErrorKind, ParseIntError},
};
use crate::utils::err_prefix;
#[derive(Copy, Clone, PartialEq)]
pub enum ParseError {
Empty,
InvalidDigit,
PosOverflow,
NegOverflow,
Zero,
Unknown,
}
impl ParseError {
pub(crate) const fn description(&self) -> &str {
use ParseError::*;
match self {
Empty => "attempt to parse integer from empty string",
InvalidDigit => "attempt to parse integer from string containing invalid digit",
PosOverflow => {
"attempt to parse integer too large to be represented by the target type"
}
NegOverflow => {
"attempt to parse integer too small to be represented by the target type"
}
Zero => {
"attempt to parse the integer `0` which cannot be represented by the target type"
}
Unknown => panic!("unknown error occurred"),
}
}
}
impl Display for ParseError {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{} {}", err_prefix!(), self.description())
}
}
impl Debug for ParseError {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
Display::fmt(&self, f)
}
}
impl From<ParseIntError> for ParseError {
fn from(e: ParseIntError) -> ParseError {
from_int_error_kind(e.kind())
}
}
impl From<bnum::errors::ParseIntError> for ParseError {
fn from(e: bnum::errors::ParseIntError) -> Self {
from_int_error_kind(e.kind())
}
}
impl core::error::Error for ParseError {
fn description(&self) -> &str {
self.description()
}
}
pub(crate) const fn from_int_error_kind(e: &IntErrorKind) -> ParseError {
match e {
IntErrorKind::Empty => ParseError::Empty,
IntErrorKind::InvalidDigit => ParseError::InvalidDigit,
IntErrorKind::PosOverflow => ParseError::PosOverflow,
IntErrorKind::NegOverflow => ParseError::NegOverflow,
IntErrorKind::Zero => ParseError::Zero,
_ => ParseError::Unknown,
}
}