websocket_simple/
result.rs1use std::fmt;
2use std::io;
3use std::borrow::Cow;
4use std::str::Utf8Error;
5use std::result::Result as StdResult;
6use std::error::Error as StdError;
7use std::convert::{From, Into};
8
9use httparse;
10#[cfg(feature="ssl")]
11use openssl::ssl::error::SslError;
12
13pub type Result<T> = StdResult<T, Error>;
14
15#[derive(Debug)]
17pub enum Kind {
18 CloseSingal,
20 OutNotEnough,
22 Internal,
25 Capacity,
30 Protocol,
34 Encoding(Utf8Error),
38 Io(io::Error),
41 Http(httparse::Error),
45 #[cfg(feature="ssl")]
47 Ssl(SslError),
48 Custom(Box<StdError + Send + Sync>),
52}
53
54pub struct Error {
56 pub kind: Kind,
57 pub details: Cow<'static, str>,
58}
59
60impl Error {
61
62 pub fn new<I>(kind: Kind, details: I) -> Error
63 where I: Into<Cow<'static, str>>
64 {
65 Error {
66 kind: kind,
67 details: details.into(),
68 }
69 }
70
71 pub fn into_box(self) -> Box<StdError> {
72 match self.kind {
73 Kind::Custom(err) => err,
74 _ => Box::new(self),
75 }
76 }
77}
78
79impl fmt::Debug for Error {
80 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
81 if self.details.len() > 0 {
82 write!(f, "WS Error <{:?}>: {}", self.kind, self.details)
83 } else {
84 write!(f, "WS Error <{:?}>", self.kind)
85 }
86 }
87}
88
89impl fmt::Display for Error {
90
91 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
92 if self.details.len() > 0 {
93 write!(f, "{}: {}", self.description(), self.details)
94 } else {
95 write!(f, "{}", self.description())
96 }
97 }
98}
99
100impl StdError for Error {
101
102 fn description(&self) -> &str {
103 match self.kind {
104 Kind::CloseSingal => "Close Signal Error",
105 Kind::OutNotEnough => "Outbuff NotEnough Error",
106 Kind::Internal => "Internal Application Error",
107 Kind::Capacity => "WebSocket at Capacity",
108 Kind::Protocol => "WebSocket Protocol Error",
109 Kind::Encoding(ref err) => err.description(),
110 Kind::Io(ref err) => err.description(),
111 Kind::Http(_) => "Unable to parse HTTP",
112 #[cfg(feature="ssl")]
113 Kind::Ssl(ref err) => err.description(),
114 Kind::Custom(ref err) => err.description(),
115 }
116 }
117
118 fn cause(&self) -> Option<&StdError> {
119 match self.kind {
120 Kind::Encoding(ref err) => Some(err),
121 Kind::Io(ref err) => Some(err),
122 #[cfg(feature="ssl")]
123 Kind::Ssl(ref err) => Some(err),
124 Kind::Custom(ref err) => Some(err.as_ref()),
125 _ => None,
126 }
127 }
128}
129
130impl From<io::Error> for Error {
131 fn from(err: io::Error) -> Error {
132 Error::new(Kind::Io(err), "")
133 }
134}
135
136impl From<httparse::Error> for Error {
137
138 fn from(err: httparse::Error) -> Error {
139 let details = match err {
140 httparse::Error::HeaderName => "Invalid byte in header name.",
141 httparse::Error::HeaderValue => "Invalid byte in header value.",
142 httparse::Error::NewLine => "Invalid byte in new line.",
143 httparse::Error::Status => "Invalid byte in Response status.",
144 httparse::Error::Token => "Invalid byte where token is required.",
145 httparse::Error::TooManyHeaders => "Parsed more headers than provided buffer can contain.",
146 httparse::Error::Version => "Invalid byte in HTTP version.",
147 };
148
149 Error::new(Kind::Http(err), details)
150 }
151
152}
153
154impl From<Utf8Error> for Error {
155 fn from(err: Utf8Error) -> Error {
156 Error::new(Kind::Encoding(err), "")
157 }
158}
159
160#[cfg(feature="ssl")]
161impl From<SslError> for Error {
162 fn from(err: SslError) -> Error {
163 Error::new(Kind::Ssl(err), "")
164 }
165}
166
167impl<B> From<Box<B>> for Error
168 where B: StdError + Send + Sync + 'static
169{
170 fn from(err: Box<B>) -> Error {
171 Error::new(Kind::Custom(err), "")
172 }
173}