snapcast_control/protocol/
errors.rs

1/// an error returned from the snapcast server
2#[derive(Debug, Clone, PartialEq, thiserror::Error)]
3pub enum SnapcastError {
4  #[error("Parse error: {0}")]
5  ParseError(String),
6  #[error("Invalid request: {0}")]
7  InvalidRequest(String),
8  #[error("Method not found: {0}")]
9  MethodNotFound(String),
10  #[error("Invalid params: {0}")]
11  InvalidParams(String),
12  #[error("Internal error: {0}")]
13  InternalError(String),
14  #[error("Unknown error: {0}")]
15  Unknown(i64, String),
16}
17
18impl SnapcastError {
19  pub fn code(&self) -> i64 {
20    match self {
21      SnapcastError::ParseError(_) => -32700,
22      SnapcastError::InvalidRequest(_) => -32600,
23      SnapcastError::MethodNotFound(_) => -32601,
24      SnapcastError::InvalidParams(_) => -32602,
25      SnapcastError::InternalError(_) => -32603,
26      SnapcastError::Unknown(code, _) => *code,
27    }
28  }
29
30  pub fn message(&self) -> &str {
31    match self {
32      SnapcastError::ParseError(message) => message,
33      SnapcastError::InvalidRequest(message) => message,
34      SnapcastError::MethodNotFound(message) => message,
35      SnapcastError::InvalidParams(message) => message,
36      SnapcastError::InternalError(message) => message,
37      SnapcastError::Unknown(_, message) => message,
38    }
39  }
40}
41
42impl<'de> serde::Deserialize<'de> for SnapcastError {
43  fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
44    use serde::de::Error;
45    use serde_json::Value;
46
47    let value = Value::deserialize(d)?;
48    let code = if let Some(code) = value.get("code").and_then(Value::as_i64) {
49      code
50    } else {
51      return Err(D::Error::missing_field("code"));
52    };
53    let message = if let Some(message) = value.get("message").and_then(Value::as_str) {
54      message.to_string()
55    } else {
56      return Err(D::Error::missing_field("message"));
57    };
58
59    Ok(match code {
60      -32700 => SnapcastError::ParseError(message),
61      -32600 => SnapcastError::InvalidRequest(message),
62      -32601 => SnapcastError::MethodNotFound(message),
63      -32602 => SnapcastError::InvalidParams(message),
64      -32603 => SnapcastError::InternalError(message),
65      code => SnapcastError::Unknown(code, message),
66    })
67  }
68}
69
70impl serde::Serialize for SnapcastError {
71  fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
72  where
73    S: serde::Serializer,
74  {
75    use serde::ser::SerializeStruct;
76
77    let mut state = serializer.serialize_struct("SnapcastError", 2)?;
78    state.serialize_field("code", &self.code())?;
79    state.serialize_field("message", &self.message())?;
80    state.end()
81  }
82}
83
84/// an error controlling a stream
85#[derive(Debug)]
86pub enum StreamControlError {
87  NotFound(String),
88  CannotBeControlled(String),
89  CannotNext(String),
90  CannotPrevious(String),
91  CannotPlay(String),
92  CannotPause(String),
93  CannotSeek(String),
94  CannotControl(String),
95  InvalidParams(String),
96  Unknown(i64, String),
97}
98
99impl StreamControlError {
100  pub fn code(&self) -> i64 {
101    match self {
102      StreamControlError::NotFound(_) => -32603,
103      StreamControlError::CannotBeControlled(_) => 1,
104      StreamControlError::CannotNext(_) => 2,
105      StreamControlError::CannotPrevious(_) => 3,
106      StreamControlError::CannotPlay(_) => 4,
107      StreamControlError::CannotPause(_) => 5,
108      StreamControlError::CannotSeek(_) => 6,
109      StreamControlError::CannotControl(_) => 7,
110      StreamControlError::InvalidParams(_) => -32602,
111      StreamControlError::Unknown(code, _) => *code,
112    }
113  }
114
115  pub fn message(&self) -> &str {
116    match self {
117      StreamControlError::NotFound(message) => message,
118      StreamControlError::CannotBeControlled(message) => message,
119      StreamControlError::CannotNext(message) => message,
120      StreamControlError::CannotPrevious(message) => message,
121      StreamControlError::CannotPlay(message) => message,
122      StreamControlError::CannotPause(message) => message,
123      StreamControlError::CannotSeek(message) => message,
124      StreamControlError::CannotControl(message) => message,
125      StreamControlError::InvalidParams(message) => message,
126      StreamControlError::Unknown(_, message) => message,
127    }
128  }
129}
130
131impl<'de> serde::Deserialize<'de> for StreamControlError {
132  fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
133    use serde::de::Error;
134    use serde_json::Value;
135
136    let value = Value::deserialize(d)?;
137    let code = if let Some(code) = value.get("code").and_then(Value::as_i64) {
138      code
139    } else {
140      return Err(D::Error::missing_field("code"));
141    };
142    let message = if let Some(message) = value.get("message").and_then(Value::as_str) {
143      message.to_string()
144    } else {
145      return Err(D::Error::missing_field("message"));
146    };
147
148    Ok(match code {
149      -32603 => StreamControlError::NotFound(message),
150      1 => StreamControlError::CannotBeControlled(message),
151      2 => StreamControlError::CannotNext(message),
152      3 => StreamControlError::CannotPrevious(message),
153      4 => StreamControlError::CannotPlay(message),
154      5 => StreamControlError::CannotPause(message),
155      6 => StreamControlError::CannotSeek(message),
156      7 => StreamControlError::CannotControl(message),
157      -32602 => StreamControlError::InvalidParams(message),
158      code => StreamControlError::Unknown(code, message),
159    })
160  }
161}
162
163impl serde::Serialize for StreamControlError {
164  fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
165  where
166    S: serde::Serializer,
167  {
168    use serde::ser::SerializeStruct;
169
170    let mut state = serializer.serialize_struct("StreamControlError", 2)?;
171    state.serialize_field("code", &self.code())?;
172    state.serialize_field("message", &self.message())?;
173    state.end()
174  }
175}
176
177#[cfg(test)]
178mod tests {
179  use super::*;
180
181  #[test]
182  fn serialize_errors() {
183    let error = SnapcastError::ParseError("Parse error".to_string());
184
185    let json = serde_json::to_string(&error).unwrap();
186    let expected = r#"{"code":-32700,"message":"Parse error"}"#;
187
188    assert_eq!(json, expected);
189  }
190
191  #[test]
192  fn deserialize_errors() {
193    let json = r#"{"code": -32700, "message": "Parse error"}"#;
194    let error: SnapcastError = serde_json::from_str(json).unwrap();
195    assert_eq!(error, SnapcastError::ParseError("Parse error".to_string()));
196
197    let json = r#"{"code": -32600, "message": "Invalid request"}"#;
198    let error: SnapcastError = serde_json::from_str(json).unwrap();
199    assert_eq!(error, SnapcastError::InvalidRequest("Invalid request".to_string()));
200
201    let json = r#"{"code": -32601, "message": "Method not found"}"#;
202    let error: SnapcastError = serde_json::from_str(json).unwrap();
203    assert_eq!(error, SnapcastError::MethodNotFound("Method not found".to_string()));
204
205    let json = r#"{"code": -32602, "message": "Invalid params"}"#;
206    let error: SnapcastError = serde_json::from_str(json).unwrap();
207    assert_eq!(error, SnapcastError::InvalidParams("Invalid params".to_string()));
208
209    let json = r#"{"code": -32603, "message": "Internal error"}"#;
210    let error: SnapcastError = serde_json::from_str(json).unwrap();
211    assert_eq!(error, SnapcastError::InternalError("Internal error".to_string()));
212  }
213}