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 AsRef<str>) -> Self {
18        Self::with(format!("missing value: {}", value_name.as_ref()))
19    }
20
21    pub(crate) fn invalid_type(type_name: impl AsRef<str>) -> Self {
22        Self::with(format!("invalid type for {}", type_name.as_ref()))
23    }
24
25    pub(crate) fn invalid_value(value_name: impl AsRef<str>) -> Self {
26        Self::with(format!("invalid value {}", value_name.as_ref()))
27    }
28
29    pub(crate) const fn from_static_str(msg: &'static str) -> Self {
30        Self { inner: InnerError::Raw(Cow::Borrowed(msg)), }
31    }
32
33    pub fn with(msg: impl Into<Cow<'static, str>>) -> Self {
34        Self { inner: InnerError::Raw(msg.into()) }
35    }
36}
37
38impl From<crate::Error> for std::io::Error {
39
40    fn from(e: crate::Error) -> std::io::Error {
41        match e.inner {
42            InnerError::Io(e) => e,
43            e => std::io::Error::new(std::io::ErrorKind::Other, e)
44        }
45    }
46}
47
48impl From<crate::Error> for tauri::Error {
49
50    fn from(e: crate::Error) -> tauri::Error {
51        match e.inner {
52            InnerError::Tauri(e) => e,
53            InnerError::Io(e) => tauri::Error::Io(e),
54
55            #[cfg(target_os = "android")]
56            InnerError::PluginInvoke(e) => tauri::Error::PluginInvoke(e),
57
58            e => tauri::Error::Anyhow(e.into()),
59        }
60    }
61}
62
63
64#[derive(Debug, thiserror::Error)]
65enum InnerError {
66    #[error("{0}")]
67    Raw(Cow<'static, str>),
68
69    #[cfg(target_os = "android")]
70    #[error(transparent)]
71    PluginInvoke(tauri::plugin::mobile::PluginInvokeError),
72
73    #[cfg(target_os = "android")]
74    #[error(transparent)]
75    Base64Decode(base64::DecodeError),
76
77    #[error(transparent)]
78    Io(std::io::Error),
79
80    #[error(transparent)]
81    ParseInt(std::num::ParseIntError),
82
83    #[error(transparent)]
84    SerdeJson(serde_json::Error),
85
86    #[error(transparent)]
87    Tauri(tauri::Error),
88
89    #[error(transparent)]
90    TauriHttpHeaderToStr(tauri::http::header::ToStrError),
91
92    #[error(transparent)]
93    TauriPluginFs(tauri_plugin_fs::Error),
94
95    #[error(transparent)]
96    StdSystemTime(std::time::SystemTimeError),
97
98    #[error(transparent)]
99    Utf8Error(std::str::Utf8Error),
100}
101
102macro_rules! impl_into_err_from_inner {
103    ($from:ty, $e:pat => $a:expr) => {
104        impl From<$from> for crate::Error {
105            fn from($e: $from) -> crate::Error {
106                $a
107            }
108        }
109    };
110}
111
112#[cfg(target_os = "android")]
113impl_into_err_from_inner!(tauri::plugin::mobile::PluginInvokeError, e => crate::Error { inner: InnerError::PluginInvoke(e) });
114
115#[cfg(target_os = "android")]
116impl_into_err_from_inner!(base64::DecodeError, e => crate::Error { inner: InnerError::Base64Decode(e) });
117
118impl_into_err_from_inner!(std::io::Error, e => crate::Error { inner: InnerError::Io(e) });
119impl_into_err_from_inner!(std::num::ParseIntError, e => crate::Error { inner: InnerError::ParseInt(e) });
120impl_into_err_from_inner!(serde_json::Error, e => crate::Error { inner: InnerError::SerdeJson(e) });
121impl_into_err_from_inner!(tauri::Error, e => crate::Error { inner: InnerError::Tauri(e) });
122impl_into_err_from_inner!(tauri::http::header::ToStrError, e => crate::Error { inner: InnerError::TauriHttpHeaderToStr(e) });
123impl_into_err_from_inner!(tauri_plugin_fs::Error, e => crate::Error { inner: InnerError::TauriPluginFs(e) });
124impl_into_err_from_inner!(std::time::SystemTimeError, e => crate::Error { inner: InnerError::StdSystemTime(e) });
125impl_into_err_from_inner!(std::str::Utf8Error, e => crate::Error { inner: InnerError::Utf8Error(e) });
126
127impl<W> From<std::io::IntoInnerError<W>> for crate::Error {
128    fn from(e: std::io::IntoInnerError<W>) -> crate::Error {
129        crate::Error { inner: InnerError::Io(e.into_error()) }
130    }
131}
132
133impl<T> From<std::sync::PoisonError<T>> for crate::Error {
134    fn from(_: std::sync::PoisonError<T>) -> crate::Error {
135        crate::Error::with("thread poisoned")
136    }
137}
138
139impl Serialize for crate::Error {
140
141    fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
142    where
143        S: Serializer,
144    {
145        match &self.inner {
146            InnerError::Raw(msg) => serializer.serialize_str(&msg),
147            e => serializer.serialize_str(&e.to_string())
148        }
149    }
150}