Skip to main content

tauri_plugin_android_fs/models/
error.rs

1use std::borrow::Cow;
2use serde::{ser::Serializer, Serialize};
3
4#[derive(Debug, thiserror::Error)]
5#[error(transparent)]
6pub struct Error {
7    inner: InnerError
8}
9
10#[allow(unused)]
11impl crate::Error {
12
13    pub(crate) const NOT_ANDROID: Self = Self::from_static_str(
14        "unsupported platform; only Android is supported"
15    );
16
17    pub(crate) fn missing_value(value_name: impl std::fmt::Display) -> Self {
18        Self::with(format!("missing value: {value_name}"))
19    }
20
21    pub(crate) fn invalid_type(type_name: impl std::fmt::Display) -> Self {
22        Self::with(format!("invalid type for {type_name}"))
23    }
24
25    pub(crate) fn invalid_uri_scheme(uri: impl std::fmt::Display) -> Self {
26        Self::with(format!("invalid URI scheme: {uri}"))
27    }
28
29    pub(crate) fn invalid_value(value_name: impl std::fmt::Display) -> Self {
30        Self::with(format!("invalid value {value_name}"))
31    }
32
33    pub(crate) const fn from_static_str(msg: &'static str) -> Self {
34        Self { inner: InnerError::Raw(Cow::Borrowed(msg)), }
35    }
36
37    pub fn with(msg: impl Into<Cow<'static, str>>) -> Self {
38        Self { inner: InnerError::Raw(msg.into()) }
39    }
40}
41
42impl From<crate::Error> for std::io::Error {
43
44    fn from(e: crate::Error) -> std::io::Error {
45        match e.inner {
46            InnerError::Io(e) => e,
47            e => std::io::Error::new(std::io::ErrorKind::Other, e)
48        }
49    }
50}
51
52impl From<crate::Error> for tauri::Error {
53
54    fn from(e: crate::Error) -> tauri::Error {
55        match e.inner {
56            InnerError::Tauri(e) => e,
57            InnerError::Io(e) => tauri::Error::Io(e),
58
59            #[cfg(target_os = "android")]
60            InnerError::PluginInvoke(e) => tauri::Error::PluginInvoke(e),
61
62            e => tauri::Error::Anyhow(e.into()),
63        }
64    }
65}
66
67
68#[derive(Debug, thiserror::Error)]
69enum InnerError {
70    #[error("{0}")]
71    Raw(Cow<'static, str>),
72
73    #[cfg(target_os = "android")]
74    #[error(transparent)]
75    PluginInvoke(tauri::plugin::mobile::PluginInvokeError),
76
77    #[cfg(target_os = "android")]
78    #[error(transparent)]
79    Base64Decode(base64::DecodeError),
80
81    #[error(transparent)]
82    Io(std::io::Error),
83
84    #[error(transparent)]
85    Fmt(std::fmt::Error),
86
87    #[error(transparent)]
88    ParseInt(std::num::ParseIntError),
89
90    #[error(transparent)]
91    ParseFloat(std::num::ParseFloatError),
92
93    #[error(transparent)]
94    ParseBool(std::str::ParseBoolError),
95
96    #[error(transparent)]
97    SerdeJson(serde_json::Error),
98
99    #[error(transparent)]
100    Tauri(tauri::Error),
101
102    #[error(transparent)]
103    TauriHttp(tauri::http::Error),
104
105    #[error(transparent)]
106    TauriHttpHeaderToStr(tauri::http::header::ToStrError),
107
108    #[error(transparent)]
109    TauriPluginFs(tauri_plugin_fs::Error),
110
111    #[error(transparent)]
112    StdSystemTime(std::time::SystemTimeError),
113
114    #[error(transparent)]
115    Utf8Error(std::str::Utf8Error),
116}
117
118macro_rules! impl_into_err_from_inner {
119    ($from:ty, $e:pat => $a:expr) => {
120        impl From<$from> for crate::Error {
121            fn from($e: $from) -> crate::Error {
122                $a
123            }
124        }
125    };
126}
127
128#[cfg(target_os = "android")]
129impl_into_err_from_inner!(tauri::plugin::mobile::PluginInvokeError, e => crate::Error { inner: InnerError::PluginInvoke(e) });
130
131#[cfg(target_os = "android")]
132impl_into_err_from_inner!(base64::DecodeError, e => crate::Error { inner: InnerError::Base64Decode(e) });
133
134impl_into_err_from_inner!(std::io::Error, e => crate::Error { inner: InnerError::Io(e) });
135impl_into_err_from_inner!(std::fmt::Error, e => crate::Error { inner: InnerError::Fmt(e) });
136impl_into_err_from_inner!(std::num::ParseIntError, e => crate::Error { inner: InnerError::ParseInt(e) });
137impl_into_err_from_inner!(std::num::ParseFloatError, e => crate::Error { inner: InnerError::ParseFloat(e) });
138impl_into_err_from_inner!(std::str::ParseBoolError, e => crate::Error { inner: InnerError::ParseBool(e) });
139impl_into_err_from_inner!(serde_json::Error, e => crate::Error { inner: InnerError::SerdeJson(e) });
140impl_into_err_from_inner!(tauri::Error, e => crate::Error { inner: InnerError::Tauri(e) });
141impl_into_err_from_inner!(tauri::http::Error, e => crate::Error { inner: InnerError::TauriHttp(e) });
142impl_into_err_from_inner!(tauri::http::header::ToStrError, e => crate::Error { inner: InnerError::TauriHttpHeaderToStr(e) });
143impl_into_err_from_inner!(tauri_plugin_fs::Error, e => crate::Error { inner: InnerError::TauriPluginFs(e) });
144impl_into_err_from_inner!(std::time::SystemTimeError, e => crate::Error { inner: InnerError::StdSystemTime(e) });
145impl_into_err_from_inner!(std::str::Utf8Error, e => crate::Error { inner: InnerError::Utf8Error(e) });
146impl_into_err_from_inner!(&'static str, e => crate::Error { inner: InnerError::Raw(e.into()) });
147
148impl<W> From<std::io::IntoInnerError<W>> for crate::Error {
149    fn from(e: std::io::IntoInnerError<W>) -> crate::Error {
150        crate::Error { inner: InnerError::Io(e.into_error()) }
151    }
152}
153
154impl<T> From<std::sync::PoisonError<T>> for crate::Error {
155    fn from(_: std::sync::PoisonError<T>) -> crate::Error {
156        crate::Error::with("thread poisoned")
157    }
158}
159
160impl Serialize for crate::Error {
161
162    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
163    where
164        S: Serializer,
165    {
166        match &self.inner {
167            InnerError::Raw(msg) => serializer.serialize_str(&msg),
168            e => serializer.serialize_str(&e.to_string())
169        }
170    }
171}