Skip to main content

haki_dl/
error.rs

1//! Stable error type for the public API.
2
3use std::fmt;
4
5/// Result alias used by public APIs.
6pub type Result<T> = std::result::Result<T, Error>;
7
8/// Error categories returned by public APIs.
9#[derive(Debug)]
10pub enum Error {
11    /// A manifest or media protocol rule failed.
12    Protocol { message: String },
13    /// An HTTP operation failed.
14    Http { message: String },
15    /// A filesystem or stream operation failed.
16    Io(std::io::Error),
17    /// A decryption operation failed.
18    Decrypt { message: String },
19    /// A mux or merge operation failed.
20    Mux { message: String },
21    /// A subtitle operation failed.
22    Subtitle { message: String },
23    /// A live-recording operation failed.
24    Live { message: String },
25    /// Configuration or request validation failed.
26    Config { message: String },
27    /// The caller cancelled the operation.
28    UserCancelled,
29    /// A compatibility profile rejected the requested behavior.
30    Compatibility { message: String },
31}
32
33impl Error {
34    /// Creates a protocol error.
35    pub fn protocol(message: impl Into<String>) -> Self {
36        Self::Protocol {
37            message: message.into(),
38        }
39    }
40
41    /// Creates an HTTP error.
42    pub fn http(message: impl Into<String>) -> Self {
43        Self::Http {
44            message: message.into(),
45        }
46    }
47
48    /// Creates a decryption error.
49    pub fn decrypt(message: impl Into<String>) -> Self {
50        Self::Decrypt {
51            message: message.into(),
52        }
53    }
54
55    /// Creates a mux error.
56    pub fn mux(message: impl Into<String>) -> Self {
57        Self::Mux {
58            message: message.into(),
59        }
60    }
61
62    /// Creates a subtitle error.
63    pub fn subtitle(message: impl Into<String>) -> Self {
64        Self::Subtitle {
65            message: message.into(),
66        }
67    }
68
69    /// Creates a live-recording error.
70    pub fn live(message: impl Into<String>) -> Self {
71        Self::Live {
72            message: message.into(),
73        }
74    }
75
76    /// Creates a configuration error.
77    pub fn config(message: impl Into<String>) -> Self {
78        Self::Config {
79            message: message.into(),
80        }
81    }
82
83    /// Creates a compatibility error.
84    pub fn compatibility(message: impl Into<String>) -> Self {
85        Self::Compatibility {
86            message: message.into(),
87        }
88    }
89
90    pub(crate) fn compatibility_message(&self) -> String {
91        match self {
92            Self::Protocol { message }
93            | Self::Http { message }
94            | Self::Decrypt { message }
95            | Self::Mux { message }
96            | Self::Subtitle { message }
97            | Self::Live { message }
98            | Self::Config { message }
99            | Self::Compatibility { message } => message.clone(),
100            Self::Io(error) => error.to_string(),
101            Self::UserCancelled => "operation cancelled".to_string(),
102        }
103    }
104}
105
106impl fmt::Display for Error {
107    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
108        match self {
109            Self::Protocol { message } => write!(f, "protocol error: {message}"),
110            Self::Http { message } => write!(f, "http error: {message}"),
111            Self::Io(error) => write!(f, "io error: {error}"),
112            Self::Decrypt { message } => write!(f, "decrypt error: {message}"),
113            Self::Mux { message } => write!(f, "mux error: {message}"),
114            Self::Subtitle { message } => write!(f, "subtitle error: {message}"),
115            Self::Live { message } => write!(f, "live error: {message}"),
116            Self::Config { message } => write!(f, "config error: {message}"),
117            Self::UserCancelled => f.write_str("operation cancelled"),
118            Self::Compatibility { message } => write!(f, "compatibility error: {message}"),
119        }
120    }
121}
122
123impl std::error::Error for Error {
124    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
125        match self {
126            Self::Io(error) => Some(error),
127            _ => None,
128        }
129    }
130}
131
132impl From<std::io::Error> for Error {
133    fn from(value: std::io::Error) -> Self {
134        Self::Io(value)
135    }
136}