Skip to main content

hyprshell_hyprland/
error.rs

1#[derive(Debug, derive_more::Display)]
2/// Error that unifies different error types used by Hyprland-rs
3pub enum HyprError {
4    /// Error coming from serde
5    SerdeError(serde_json::Error),
6    /// Error coming from std::io
7    IoError(io::Error),
8    /// Error from failing to parse HyprColor
9    InvalidHyprColorFormat,
10    /// Error from failing to parse HyprGradient
11    InvalidHyprGradiantFormat,
12    /// Error that occurs when parsing UTF-8 string
13    FromUtf8Error(std::string::FromUtf8Error),
14    /// Dispatcher returned non `ok` value
15    #[display("A dispatcher returned a non-`ok`, value which is probably an error: {_0}")]
16    NotOkDispatch(String),
17    /// Error when interacting with Hyprpaper.
18    #[cfg(feature = "hyprpaper")]
19    Hyprpaper(crate::hyprpaper::Error),
20    /// Keyword does not exist
21    InvalidOptionKey(String),
22    /// Unparsable Option
23    InvalidOptionValue,
24    /// Internal Hyprland error
25    Internal(String),
26    /// Error that occurs for other reasons. Avoid using this.
27    Other(String),
28}
29impl HyprError {
30    /// Try to get an owned version of the internal error.
31    ///
32    /// Some dependencies of hyprland do not impl Clone in their error types. This is a partial workaround.
33    ///
34    /// If it succeeds, it returns the owned version of HyprError in Ok(). Otherwise, it returns a reference to the error type.
35    pub fn try_as_cloned(&self) -> Result<Self, &Self> {
36        match self {
37            Self::SerdeError(_) => Err(self),
38            Self::IoError(_) => Err(self),
39            Self::FromUtf8Error(e) => Ok(Self::FromUtf8Error(e.clone())),
40            Self::NotOkDispatch(s) => Ok(Self::NotOkDispatch(s.clone())),
41            Self::InvalidHyprColorFormat => Ok(Self::InvalidHyprColorFormat),
42            Self::InvalidHyprGradiantFormat => Ok(Self::InvalidHyprGradiantFormat),
43            #[cfg(feature = "hyprpaper")]
44            Self::Hyprpaper(_) => Err(self),
45            Self::InvalidOptionKey(key) => Ok(Self::InvalidOptionKey(key.clone())),
46            Self::InvalidOptionValue => Ok(Self::InvalidOptionValue),
47            Self::Internal(s) => Ok(Self::Internal(s.clone())),
48            Self::Other(s) => Ok(Self::Other(s.clone())),
49        }
50    }
51    /// Create a Hyprland error with dynamic data.
52    #[inline(always)]
53    pub fn other<S: Into<String>>(other: S) -> Self {
54        Self::Other(other.into())
55    }
56}
57
58impl From<io::Error> for HyprError {
59    fn from(error: io::Error) -> Self {
60        HyprError::IoError(error)
61    }
62}
63
64impl From<serde_json::Error> for HyprError {
65    fn from(error: serde_json::Error) -> Self {
66        HyprError::SerdeError(error)
67    }
68}
69
70impl From<std::string::FromUtf8Error> for HyprError {
71    fn from(error: std::string::FromUtf8Error) -> Self {
72        HyprError::FromUtf8Error(error)
73    }
74}
75
76impl error::Error for HyprError {}
77
78/// Internal macro to return a Hyprland error
79macro_rules! hypr_err {
80    ($fmt:literal) => {
81        return Err($crate::error::HyprError::Internal(format!($fmt)))
82    };
83    (other $fmt:literal) => {
84        return Err($crate::error::HyprError::Other(format!($fmt)))
85    };
86    ($fmt:literal $(, $value:expr)+) => {
87        return Err($crate::error::HyprError::Internal(format!($fmt $(, $value)+)))
88    };
89    (other $fmt:literal $(, $value:expr)+) => {
90        return Err($crate::error::HyprError::Other(format!($fmt $(, $value)+)))
91    };
92}
93
94pub(crate) use hypr_err;
95use std::{error, io};