1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use core::fmt::{self, Debug, Display, Formatter};
use std::num::IntErrorKind;

#[derive(PartialEq, Eq, Clone)]
pub struct ParseError {
    pub kind: IntErrorKind,
}

impl ParseError {
    pub const fn kind(&self) -> &IntErrorKind {
        &self.kind
    }

    const fn description(&self) -> &str {
        match &self.kind {
            IntErrorKind::Empty => "attempt to parse integer from empty string",
            IntErrorKind::InvalidDigit => {
                "attempt to parse integer from string containing invalid digit"
            }
            IntErrorKind::PosOverflow => {
                "attempt to parse integer too large to be represented by the target type"
            }
            IntErrorKind::NegOverflow => {
                "attempt to parse integer too small to be represented by the target type"
            }
            IntErrorKind::Zero => {
                "attempt to parse the integer `0` which cannot be represented by the target type"
            }
            _ => panic!("unsupported `IntErrorKind` variant"), // necessary as `IntErrorKind` is non-exhaustive
        }
    }
}

impl ParseError {
    pub fn new(kind: IntErrorKind) -> ParseError {
        ParseError { kind }
    }
}

impl Display for ParseError {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "(num256) {}", self.description())
    }
}

impl Debug for ParseError {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        Display::fmt(&self, f)
    }
}

impl From<bnum::errors::ParseIntError> for ParseError {
    fn from(value: bnum::errors::ParseIntError) -> Self {
        ParseError {
            kind: value.kind().clone(),
        }
    }
}