1use std::error::Error;
4use std::fmt;
5use std::io;
6use std::str;
7
8use crate::wire_format::WireType;
9
10pub type ProtobufResult<T> = Result<T, ProtobufError>;
12
13#[derive(Debug)]
16pub enum WireError {
17 UnexpectedEof,
19 UnexpectedWireType(WireType),
21 IncorrectTag(u32),
23 IncompleteMap,
25 IncorrectVarint,
27 Utf8Error,
29 InvalidEnumValue(i32),
31 OverRecursionLimit,
33 TruncatedMessage,
35 Other,
37}
38
39impl fmt::Display for WireError {
40 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
41 match self {
42 WireError::Utf8Error => write!(f, "invalid UTF-8 sequence"),
43 WireError::UnexpectedWireType(..) => write!(f, "unexpected wire type"),
44 WireError::InvalidEnumValue(..) => write!(f, "invalid enum value"),
45 WireError::IncorrectTag(..) => write!(f, "incorrect tag"),
46 WireError::IncorrectVarint => write!(f, "incorrect varint"),
47 WireError::IncompleteMap => write!(f, "incomplete map"),
48 WireError::UnexpectedEof => write!(f, "unexpected EOF"),
49 WireError::OverRecursionLimit => write!(f, "over recursion limit"),
50 WireError::TruncatedMessage => write!(f, "truncated message"),
51 WireError::Other => write!(f, "other error"),
52 }
53 }
54}
55
56#[derive(Debug)]
58pub enum ProtobufError {
59 IoError(io::Error),
61 WireError(WireError),
63 Utf8(str::Utf8Error),
65 MessageNotInitialized {
67 message: &'static str,
69 },
70}
71
72impl ProtobufError {
73 #[doc(hidden)]
75 pub fn message_not_initialized(message: &'static str) -> ProtobufError {
76 ProtobufError::MessageNotInitialized { message: message }
77 }
78}
79
80impl fmt::Display for ProtobufError {
81 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82 match self {
83 &ProtobufError::IoError(ref e) => write!(f, "IO error: {}", e),
85 &ProtobufError::WireError(ref e) => fmt::Display::fmt(e, f),
86 &ProtobufError::Utf8(ref e) => write!(f, "{}", e),
87 &ProtobufError::MessageNotInitialized { .. } => write!(f, "not all message fields set"),
88 }
89 }
90}
91
92impl Error for ProtobufError {
93 #[allow(deprecated)] fn description(&self) -> &str {
95 match self {
96 &ProtobufError::IoError(ref e) => e.description(),
98 &ProtobufError::WireError(ref e) => match *e {
99 WireError::Utf8Error => "invalid UTF-8 sequence",
100 WireError::UnexpectedWireType(..) => "unexpected wire type",
101 WireError::InvalidEnumValue(..) => "invalid enum value",
102 WireError::IncorrectTag(..) => "incorrect tag",
103 WireError::IncorrectVarint => "incorrect varint",
104 WireError::IncompleteMap => "incomplete map",
105 WireError::UnexpectedEof => "unexpected EOF",
106 WireError::OverRecursionLimit => "over recursion limit",
107 WireError::TruncatedMessage => "truncated message",
108 WireError::Other => "other error",
109 },
110 &ProtobufError::Utf8(ref e) => &e.description(),
111 &ProtobufError::MessageNotInitialized { .. } => "not all message fields set",
112 }
113 }
114
115 fn cause(&self) -> Option<&dyn Error> {
116 match self {
117 &ProtobufError::IoError(ref e) => Some(e),
118 &ProtobufError::Utf8(ref e) => Some(e),
119 &ProtobufError::WireError(..) => None,
120 &ProtobufError::MessageNotInitialized { .. } => None,
121 }
122 }
123}
124
125impl From<io::Error> for ProtobufError {
126 fn from(err: io::Error) -> Self {
127 ProtobufError::IoError(err)
128 }
129}
130
131impl From<str::Utf8Error> for ProtobufError {
132 fn from(err: str::Utf8Error) -> Self {
133 ProtobufError::Utf8(err)
134 }
135}
136
137impl From<ProtobufError> for io::Error {
138 fn from(err: ProtobufError) -> Self {
139 match err {
140 ProtobufError::IoError(e) => e,
141 ProtobufError::WireError(e) => {
142 io::Error::new(io::ErrorKind::InvalidData, ProtobufError::WireError(e))
143 }
144 ProtobufError::MessageNotInitialized { message: msg } => io::Error::new(
145 io::ErrorKind::InvalidInput,
146 ProtobufError::MessageNotInitialized { message: msg },
147 ),
148 e => io::Error::new(io::ErrorKind::Other, Box::new(e)),
149 }
150 }
151}