1use std::convert::From;
16use std::error::Error as StdError;
17use std::fmt;
18use std::io::Error as IoError;
19use std::num::{ParseFloatError, ParseIntError};
20use std::result;
21use std::str::FromStr;
22use std::string::ParseError as StringParseError;
23
24#[cfg_attr(feature = "serde", derive(serde_repr::Serialize_repr, serde_repr::Deserialize_repr))]
27#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
28#[repr(u8)]
29pub enum ErrorCode {
30 NotList = 1,
32 Argument = 2,
34 Password = 3,
36 Permission = 4,
38 UnknownCmd = 5,
40 NoExist = 50,
42 PlaylistMax = 51,
44 System = 52,
46 PlaylistLoad = 53,
48 UpdateAlready = 54,
50 PlayerSync = 55,
52 Exist = 56,
54}
55
56impl FromStr for ErrorCode {
57 type Err = ParseError;
58 fn from_str(s: &str) -> result::Result<ErrorCode, ParseError> {
59 use self::ErrorCode::*;
60 match s.parse()? {
61 1 => Ok(NotList),
62 2 => Ok(Argument),
63 3 => Ok(Password),
64 4 => Ok(Permission),
65 5 => Ok(UnknownCmd),
66
67 50 => Ok(NoExist),
68 51 => Ok(PlaylistMax),
69 52 => Ok(System),
70 53 => Ok(PlaylistLoad),
71 54 => Ok(UpdateAlready),
72 55 => Ok(PlayerSync),
73 56 => Ok(Exist),
74
75 v => Err(ParseError::BadErrorCode(v)),
76 }
77 }
78}
79
80impl StdError for ErrorCode {}
81
82impl fmt::Display for ErrorCode {
83 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
84 use self::ErrorCode::*;
85
86 let desc = match *self {
87 NotList => "not a list",
88 Argument => "invalid argument",
89 Password => "invalid password",
90 Permission => "permission",
91 UnknownCmd => "unknown command",
92
93 NoExist => "item not found",
94 PlaylistMax => "playlist overflow",
95 System => "system",
96 PlaylistLoad => "playload load",
97 UpdateAlready => "already updating",
98 PlayerSync => "player syncing",
99 Exist => "already exists",
100 };
101
102 f.write_str(desc)
103 }
104}
105
106#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
108#[derive(Debug, Clone, PartialEq)]
109pub struct ServerError {
110 pub code: ErrorCode,
112 pub pos: u16,
114 pub command: String,
116 pub detail: String,
118}
119
120impl StdError for ServerError {}
121
122impl fmt::Display for ServerError {
123 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
124 write!(f, "{} error (`{}') at {}", self.code, self.detail, self.pos)
125 }
126}
127
128impl FromStr for ServerError {
129 type Err = ParseError;
130 fn from_str(s: &str) -> result::Result<ServerError, ParseError> {
131 if let Some(s) = s.strip_prefix("ACK [") {
133 if let (Some(atsign), Some(right_bracket)) = (s.find('@'), s.find(']')) {
134 match (s[..atsign].parse(), s[atsign + 1..right_bracket].parse()) {
135 (Ok(code), Ok(pos)) => {
136 let s = &s[right_bracket + 1..];
137 if let (Some(left_brace), Some(right_brace)) = (s.find('{'), s.find('}')) {
138 let command = s[left_brace + 1..right_brace].to_string();
139 let detail = s[right_brace + 1..].trim().to_string();
140 Ok(ServerError { code, pos, command, detail })
141 } else {
142 Err(ParseError::NoMessage)
143 }
144 }
145 (Err(_), _) => Err(ParseError::BadCode),
146 (_, Err(_)) => Err(ParseError::BadPos),
147 }
148 } else {
149 Err(ParseError::NoCodePos)
150 }
151 } else {
152 Err(ParseError::NotAck)
153 }
154 }
155}
156#[derive(Debug)]
161pub enum Error {
162 Io(IoError),
164 Parse(ParseError),
166 Proto(ProtoError),
168 Server(ServerError),
170}
171
172pub type Result<T> = result::Result<T, Error>;
174
175impl StdError for Error {
176 fn source(&self) -> Option<&(dyn StdError + 'static)> {
177 match *self {
178 Error::Io(ref err) => Some(err),
179 Error::Parse(ref err) => Some(err),
180 Error::Proto(ref err) => Some(err),
181 Error::Server(ref err) => Some(err),
182 }
183 }
184}
185
186impl fmt::Display for Error {
187 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
188 match *self {
189 Error::Io(ref err) => err.fmt(f),
190 Error::Parse(ref err) => err.fmt(f),
191 Error::Proto(ref err) => err.fmt(f),
192 Error::Server(ref err) => err.fmt(f),
193 }
194 }
195}
196
197impl From<IoError> for Error {
198 fn from(e: IoError) -> Error {
199 Error::Io(e)
200 }
201}
202impl From<ParseError> for Error {
203 fn from(e: ParseError) -> Error {
204 Error::Parse(e)
205 }
206}
207impl From<ProtoError> for Error {
208 fn from(e: ProtoError) -> Error {
209 Error::Proto(e)
210 }
211}
212impl From<ParseIntError> for Error {
213 fn from(e: ParseIntError) -> Error {
214 Error::Parse(ParseError::BadInteger(e))
215 }
216}
217impl From<ParseFloatError> for Error {
218 fn from(e: ParseFloatError) -> Error {
219 Error::Parse(ParseError::BadFloat(e))
220 }
221}
222impl From<ServerError> for Error {
223 fn from(e: ServerError) -> Error {
224 Error::Server(e)
225 }
226}
227
228#[derive(Debug, Clone, PartialEq)]
233pub enum ParseError {
234 BadInteger(ParseIntError),
236 BadFloat(ParseFloatError),
238 BadValue(String),
240 BadVersion,
242 NotAck,
247 BadPair,
249 BadCode,
251 BadPos,
253 NoCodePos,
255 NoMessage,
257 NoRate,
259 NoBits,
261 NoChans,
263 BadRate(ParseIntError),
265 BadBits(ParseIntError),
267 BadChans(ParseIntError),
269 BadState(String),
271 BadErrorCode(usize),
273}
274
275impl StdError for ParseError {}
276
277impl fmt::Display for ParseError {
278 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
279 use self::ParseError::*;
280
281 let desc = match *self {
282 BadInteger(_) => "invalid integer",
283 BadFloat(_) => "invalid float",
284 BadValue(_) => "invalid value",
285 BadVersion => "invalid version",
286 NotAck => "not an ACK",
287 BadPair => "invalid pair",
288 BadCode => "invalid code",
289 BadPos => "invalid position",
290 NoCodePos => "missing code and position",
291 NoMessage => "missing position",
292 NoRate => "missing audio format rate",
293 NoBits => "missing audio format bits",
294 NoChans => "missing audio format channels",
295 BadRate(_) => "invalid audio format rate",
296 BadBits(_) => "invalid audio format bits",
297 BadChans(_) => "invalid audio format channels",
298 BadState(_) => "invalid playing state",
299 BadErrorCode(_) => "unknown error code",
300 };
301
302 write!(f, "{}", desc)
303 }
304}
305
306impl From<ParseIntError> for ParseError {
307 fn from(e: ParseIntError) -> ParseError {
308 ParseError::BadInteger(e)
309 }
310}
311
312impl From<ParseFloatError> for ParseError {
313 fn from(e: ParseFloatError) -> ParseError {
314 ParseError::BadFloat(e)
315 }
316}
317
318impl From<StringParseError> for ParseError {
319 fn from(e: StringParseError) -> ParseError {
320 match e {}
321 }
322}
323#[derive(Debug, Clone, PartialEq)]
332pub enum ProtoError {
333 NotOk,
335 NotPair,
337 BadBanner,
339 NoField(&'static str),
341 BadSticker,
343}
344
345impl StdError for ProtoError {}
346
347impl fmt::Display for ProtoError {
348 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
349 let desc = match *self {
350 ProtoError::NotOk => "OK expected",
351 ProtoError::NotPair => "pair expected",
352 ProtoError::BadBanner => "banner error",
353 ProtoError::NoField(_) => "missing field",
354 ProtoError::BadSticker => "sticker error",
355 };
356
357 write!(f, "{}", desc)
358 }
359}
360