1use std::{
2 any::Any,
3 error::Error,
4 fmt::{Display, Formatter},
5 panic::panic_any,
6};
7
8use pyo3::{exceptions::PyRuntimeError, prelude::*};
9
10#[derive(Debug)]
40pub struct TauriError(tauri::Error);
41
42impl Display for TauriError {
43 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
44 Display::fmt(&self.0, f)
45 }
46}
47
48impl Error for TauriError {}
49
50impl From<TauriError> for PyErr {
51 fn from(value: TauriError) -> Self {
52 PyRuntimeError::new_err(value.0.to_string())
53 }
54}
55
56impl From<tauri::Error> for TauriError {
57 fn from(value: tauri::Error) -> Self {
58 Self(value)
59 }
60}
61
62pub type TauriResult<T> = Result<T, TauriError>;
63
64pub(crate) trait PyResultExt {
66 type Output;
67
68 fn unwrap_unraisable_py_result<M>(
69 self,
70 py: Python<'_>,
71 obj: Option<&Bound<'_, PyAny>>,
72 msg: impl FnOnce() -> M,
73 ) -> Self::Output
74 where
75 M: Any + Send + 'static;
76}
77
78impl<T> PyResultExt for PyResult<T> {
79 type Output = T;
80
81 #[inline] fn unwrap_unraisable_py_result<M>(
83 self,
84 py: Python<'_>,
85 obj: Option<&Bound<'_, PyAny>>,
86 msg: impl FnOnce() -> M,
87 ) -> Self::Output
88 where
89 M: Any + Send + 'static,
90 {
91 match self {
92 Ok(v) => v,
93 Err(err) => {
94 err.write_unraisable(py, obj);
98 panic_any(msg());
102 }
103 }
104 }
105}
106
107macro_rules! delegate_inner {
108 ($slf:expr, $func:ident, $($arg:expr),*) => {
109 $slf.0
110 .inner_ref()
111 .$func($($arg),*)
112 .map_err($crate::utils::TauriError::from)
113 .map_err(pyo3::PyErr::from)
114 };
115}
116
117pub(crate) use delegate_inner;
118
119pub(crate) fn non_exhaustive_panic() -> ! {
120 panic!("NonExhaustive is reserved for `#[non_exhaustive]`");
121}
122
123macro_rules! cfg_impl {
125 (|$cfg:meta| -> $ty:ty $body:block) => {
126 {
127 let ret: ::pyo3::PyResult::<$ty> = {
128 #[cfg($cfg)]
129 $body
130 #[cfg(not($cfg))]
131 {
132 use pyo3::exceptions::PyNotImplementedError;
133
134 const MSG: &str = concat!("Available on pytauri `#[cfg(", stringify!($cfg), ")]` only.");
135 Err(PyNotImplementedError::new_err(MSG))
136 }
137 };
138 ret
139 }
140 };
141}
142
143pub(crate) use cfg_impl;