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
use std::fmt;
use std::io::ErrorKind;
use std::result::Result as StdResult;
pub enum IoError {
Phpser(Error),
Io(std::io::Error),
}
impl From<Error> for IoError {
fn from(err: Error) -> Self {
Self::Phpser(err)
}
}
impl From<std::io::Error> for IoError {
fn from(err: std::io::Error) -> Self {
if err.kind() == ErrorKind::UnexpectedEof {
Self::Phpser(Error::UnexpectedEof)
} else {
Self::Io(err)
}
}
}
#[derive(Debug, Clone, Copy)]
pub enum Error {
UnexpectedEof,
BadEncoding(usize),
BadToken(usize),
BadNumber(usize),
BadArrayKeyType(usize),
BadObjectKeyType(usize),
}
impl Error {
pub fn offset(self) -> Option<usize> {
match self {
Self::UnexpectedEof => None,
Self::BadEncoding(offset) => Some(offset),
Self::BadToken(offset) => Some(offset),
Self::BadNumber(offset) => Some(offset),
Self::BadArrayKeyType(offset) => Some(offset),
Self::BadObjectKeyType(offset) => Some(offset),
}
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::UnexpectedEof => write!(f, "unexpected end of document"),
Self::BadEncoding(_) => write!(
f,
"str is used as string type, but serialized input is not valid UTF-8"
),
Self::BadToken(_) => write!(f, "encountered invalid token"),
Self::BadNumber(_) => write!(f, "encountered malformed or out-of-range number"),
Self::BadArrayKeyType(_) => write!(f, "array key must be int or string"),
Self::BadObjectKeyType(_) => write!(f, "object key must be string"),
}?;
if let Some(offset) = self.offset() {
write!(f, " at offset {}", offset)?;
}
Ok(())
}
}
pub type Result<T = (), E = Error> = StdResult<T, E>;
pub type IoResult<T = ()> = Result<T, IoError>;