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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use core::char::ParseCharError;
use core::num::{ParseFloatError, ParseIntError};
use core::str::ParseBoolError;
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "alloc")]
use alloc::string::String;
#[cfg(feature = "std")]
use std::borrow::Borrow;
#[cfg(feature = "std")]
use std::error;
#[cfg(feature = "std")]
use std::net::AddrParseError;
#[derive(Debug)]
pub enum ParseError {
Int(ParseIntError),
Bool(ParseBoolError),
Char(ParseCharError),
Float(ParseFloatError),
#[cfg(feature = "std")]
Addr(AddrParseError),
#[cfg(feature = "std")]
Dyn(Box<dyn error::Error>),
#[cfg(not(feature = "std"))]
Dyn,
#[cfg(feature = "alloc")]
Literal {
expected: String,
found: String,
},
#[cfg(not(feature = "alloc"))]
Literal,
Multi {
expected: u8,
found: u8,
},
}
#[cfg(feature = "std")]
impl error::Error for ParseError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {
ParseError::Int(source) => Some(source),
ParseError::Bool(source) => Some(source),
ParseError::Char(source) => Some(source),
ParseError::Float(source) => Some(source),
ParseError::Addr(source) => Some(source),
ParseError::Dyn(source) => Some(source.borrow()),
ParseError::Literal { .. } => None,
ParseError::Multi { .. } => None,
}
}
}
impl core::fmt::Display for ParseError {
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
match self {
ParseError::Int(_) => write!(fmt, "unable to parse as an integer"),
ParseError::Bool(_) => write!(fmt, "unable to parse as a boolean"),
ParseError::Char(_) => write!(fmt, "unable to parse as a character"),
ParseError::Float(_) => write!(fmt, "unable to parse as a float"),
#[cfg(feature = "std")]
ParseError::Addr(_) => write!(fmt, "unable to parse as an address"),
#[cfg(feature = "std")]
ParseError::Dyn(_) => write!(fmt, "unable to parse into type"),
#[cfg(not(feature = "std"))]
ParseError::Dyn => write!(fmt, "unable to parse into type"),
#[cfg(feature = "alloc")]
ParseError::Literal { expected, found } => write!(
fmt,
"invalid literal match (expected to find {expected:?}, found {found:?})"
),
#[cfg(not(feature = "alloc"))]
ParseError::Literal => write!(fmt, "invalid literal match"),
ParseError::Multi { expected, found } => write!(
fmt,
"invalid number of items (expected to find {expected:?}, found {found:?})"
),
}
}
}
macro_rules! impl_from_parse_error {
($Ty: ty, $Id: ident) => {
impl From<$Ty> for ParseError {
fn from(source: $Ty) -> Self {
ParseError::$Id(source)
}
}
};
}
impl_from_parse_error!(ParseIntError, Int);
impl_from_parse_error!(ParseBoolError, Bool);
impl_from_parse_error!(ParseCharError, Char);
impl_from_parse_error!(ParseFloatError, Float);
#[cfg(feature = "std")]
impl_from_parse_error!(AddrParseError, Addr);
#[cfg(feature = "std")]
impl_from_parse_error!(Box<dyn error::Error>, Dyn);