1#[derive(Debug)]
5pub enum XMLError {
6 ParseError(roxmltree::Error),
8 ElementNotFound(String),
10 UnexpectedValue(String), XMLBuilderError(xml_builder::XMLError),
14}
15
16impl From<xml_builder::XMLError> for XMLError {
17 fn from(error: xml_builder::XMLError) -> Self {
18 Self::XMLBuilderError(error)
19 }
20}
21
22impl From<roxmltree::Error> for XMLError {
23 fn from(error: roxmltree::Error) -> Self {
24 Self::ParseError(error)
25 }
26}
27
28impl std::fmt::Display for XMLError {
29 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30 match self {
31 Self::ParseError(source) => write!(f, "error parsing XML: {}", source),
32 Self::ElementNotFound(details) => write!(f, "element not found {}", details),
33 Self::UnexpectedValue(details) => write!(f, "unexpected value: {}", details),
34 Self::XMLBuilderError(source) => write!(f, "error building XML: {}", source),
35 }
36 }
37}
38
39impl std::error::Error for XMLError {
40 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
41 match self {
42 Self::ElementNotFound(_) => None,
43 Self::ParseError(source) => Some(source),
44 Self::UnexpectedValue(_) => None,
45 Self::XMLBuilderError(source) => Some(source),
46 }
47 }
48}
49
50pub type UDPError = std::io::Error;
52
53#[derive(Debug)]
55pub enum SpeakerError {
56 RequestError(reqwest::Error),
58 ResponseError(reqwest::Error),
60 XMLError(XMLError),
62 InvalidInput(String),
64 SonosError(SonosError),
66}
67
68impl From<XMLError> for SpeakerError {
69 fn from(error: XMLError) -> Self {
70 Self::XMLError(error)
71 }
72}
73
74impl From<SonosError> for SpeakerError {
75 fn from(error: SonosError) -> Self {
76 Self::SonosError(error)
77 }
78}
79
80impl From<reqwest::Error> for SpeakerError {
81 fn from(error: reqwest::Error) -> Self {
82 if error.is_builder()
83 || error.is_connect()
84 || error.is_redirect()
85 || error.is_timeout()
86 || error.is_request()
87 {
88 Self::RequestError(error)
89 } else {
90 Self::ResponseError(error)
91 }
92 }
93}
94
95impl std::fmt::Display for SpeakerError {
96 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97 match self {
98 Self::InvalidInput(details) => write!(f, "invalid input: {}", details),
99 Self::RequestError(source) => write!(f, "request error: {}", source),
100 Self::ResponseError(source) => write!(f, "response error: {}", source),
101 Self::SonosError(source) => write!(f, "Sonos speaker error: {}", source),
102 Self::XMLError(source) => write!(f, "XML error: {}", source),
103 }
104 }
105}
106
107impl std::error::Error for SpeakerError {
108 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
109 match self {
110 Self::InvalidInput(_) => None,
111 Self::RequestError(source) => Some(source),
112 Self::ResponseError(source) => Some(source),
113 Self::SonosError(source) => Some(source),
114 Self::XMLError(source) => Some(source),
115 }
116 }
117}
118
119#[derive(Debug)]
121pub enum SonosError {
122 TransitionUnavailable,
124 InvalidSeekTarget,
126 Unknown(String),
128}
129
130impl SonosError {
131 pub(crate) fn from_err_code(err_code: &str, additional_details: &str) -> Self {
132 match err_code {
133 "701" => Self::TransitionUnavailable,
134 "711" => Self::InvalidSeekTarget,
135 _ => Self::Unknown(String::from(additional_details)),
136 }
137 }
138}
139
140impl std::fmt::Display for SonosError {
141 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
142 match self {
143 Self::TransitionUnavailable => write!(f, "transition unavailable"),
144 Self::InvalidSeekTarget => write!(f, "invalid seek target"),
145 Self::Unknown(s) => write!(f, "other Sonos error: {}", s),
146 }
147 }
148}
149
150impl std::error::Error for SonosError {}