1use crate::devices::RenderSpec;
2use std::fmt;
3
4#[derive(Debug)]
6pub enum Error {
7 DevicesDiscoverFail(rupnp::Error),
9 DevicesUrlParseError(String),
11 DevicesCreateError(String, rupnp::Error),
13 DevicesRenderNotFound(RenderSpec),
15 StreamingHostParseError(String),
17 StreamingFileDoesNotExist(String),
19 StreamingRemoteRenderConnectFail(String, std::io::Error),
21 StreamingIdentifyLocalAddressError(local_ip_address::Error),
23 DLNASetAVTransportURIError(rupnp::Error),
25 DLNAPlayError(rupnp::Error),
27 DLNAStreamingError(tokio::task::JoinError),
29}
30
31impl fmt::Display for Error {
32 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33 match self {
34 Error::DevicesDiscoverFail(err) => write!(f, "Failed to discover devices: {}", err),
35 Error::DevicesUrlParseError(url) => write!(f, "Failed to parse URL '{}'", url),
36 Error::DevicesCreateError(url, err) => write!(
37 f,
38 "Failed to parse and create device from '{}': {}",
39 url, err
40 ),
41 Error::DevicesRenderNotFound(render_spec) => match render_spec {
42 RenderSpec::Location(device_url) => {
43 write!(f, "No render found at '{}'", device_url)
44 }
45 RenderSpec::Query(timeout, device_query) => write!(
46 f,
47 "No render found withing {} seconds with query '{}'",
48 timeout, device_query
49 ),
50 RenderSpec::First(timeout) => {
51 write!(f, "No render found within {} seconds", timeout)
52 }
53 },
54 Error::StreamingHostParseError(addr) => {
55 write!(f, "Failed to parse host address '{}'", addr)
56 }
57 Error::StreamingFileDoesNotExist(file) => write!(f, "File '{}' does not exist", file),
58 Error::StreamingRemoteRenderConnectFail(host, err) => {
59 write!(f, "Failed to connect to remote render '{}': {}", host, err)
60 }
61 Error::StreamingIdentifyLocalAddressError(err) => {
62 write!(f, "Failed to identify local address: {}", err)
63 }
64 Error::DLNASetAVTransportURIError(err) => {
65 write!(f, "Failed to set AVTransportURI: {}", err)
66 }
67 Error::DLNAPlayError(err) => write!(f, "Failed to Play: {}", err),
68 Error::DLNAStreamingError(err) => write!(f, "Failed to stream: {}", err),
69 }
70 }
71}
72
73impl std::error::Error for Error {
74 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
75 match self {
76 Error::DevicesDiscoverFail(err) => Some(err),
77 Error::DevicesCreateError(_, err) => Some(err),
78 Error::StreamingRemoteRenderConnectFail(_, err) => Some(err),
79 Error::StreamingIdentifyLocalAddressError(err) => Some(err),
80 Error::DLNASetAVTransportURIError(err) => Some(err),
81 Error::DLNAPlayError(err) => Some(err),
82 Error::DLNAStreamingError(err) => Some(err),
83 _ => None,
84 }
85 }
86}
87
88impl From<ssdp_client::Error> for Error {
89 fn from(err: ssdp_client::Error) -> Self {
90 Error::DevicesDiscoverFail(rupnp::Error::SSDPError(err))
91 }
92}
93
94pub type Result<T, E = Error> = std::result::Result<T, E>;