pytauri_core/plugins/updater/
mod.rs

1use std::{
2    error::Error,
3    fmt::{Debug, Display, Formatter},
4};
5
6use pyo3::{exceptions::PyRuntimeError, prelude::*, types::PyDict};
7use pyo3_utils::from_py_dict::{derive_from_py_dict, FromPyDict as _};
8use tauri_plugin_updater::{self as plugin};
9
10use crate::{ext_mod::plugin::Plugin, utils::TauriError};
11
12#[derive(Debug)]
13struct PluginError(plugin::Error);
14
15impl Display for PluginError {
16    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
17        Display::fmt(&self.0, f)
18    }
19}
20
21impl Error for PluginError {}
22
23impl From<PluginError> for PyErr {
24    fn from(value: PluginError) -> Self {
25        match value.0 {
26            plugin::Error::Tauri(e) => TauriError::from(e).into(),
27            plugin::Error::Io(e) => e.into(),
28            e @ (plugin::Error::EmptyEndpoints
29                | plugin::Error::Semver(_)
30                | plugin::Error::Serialization(_)
31                | plugin::Error::ReleaseNotFound
32                | plugin::Error::UnsupportedArch
33                | plugin::Error::UnsupportedOs
34                | plugin::Error::FailedToDetermineExtractPath
35                | plugin::Error::UrlParse(_)
36                | plugin::Error::Reqwest(_)
37                | plugin::Error::TargetNotFound(_)
38                | plugin::Error::Network(_)
39                | plugin::Error::Minisign(_)
40                | plugin::Error::Base64(_)
41                | plugin::Error::SignatureUtf8(_)
42                | plugin::Error::TempDirNotOnSameMountPoint
43                | plugin::Error::BinaryNotFoundInArchive
44                | plugin::Error::TempDirNotFound
45                | plugin::Error::AuthenticationFailed
46                | plugin::Error::DebInstallFailed
47                | plugin::Error::InvalidUpdaterFormat
48                | plugin::Error::Http(_)
49                | plugin::Error::InvalidHeaderValue(_)
50                | plugin::Error::InvalidHeaderName(_)
51                | plugin::Error::FormatDate
52                | plugin::Error::InsecureTransportProtocol) => {
53                PyRuntimeError::new_err(e.to_string())
54            }
55            #[cfg(target_os = "windows")]
56            e @ plugin::Error::Extract(_) => PyRuntimeError::new_err(e.to_string()),
57            non_exhaustive => PyRuntimeError::new_err(format!(
58                "Unimplemented plugin error, please report this to the pytauri developers: {non_exhaustive}"
59            )),
60        }
61    }
62}
63
64impl From<plugin::Error> for PluginError {
65    fn from(value: plugin::Error) -> Self {
66        Self(value)
67    }
68}
69
70/// See also: [tauri_plugin_updater::Builder]
71#[non_exhaustive]
72pub struct BuilderArgs {}
73
74derive_from_py_dict!(BuilderArgs {});
75
76impl BuilderArgs {
77    fn from_kwargs(kwargs: Option<&Bound<'_, PyDict>>) -> PyResult<Option<Self>> {
78        kwargs.map(Self::from_py_dict).transpose()
79    }
80
81    fn apply_to_builder(self, builder: plugin::Builder) -> plugin::Builder {
82        let Self {} = self;
83        builder
84    }
85}
86
87/// See also: [tauri_plugin_updater::Builder]
88#[pyclass(frozen)]
89#[non_exhaustive]
90pub struct Builder;
91
92#[pymethods]
93impl Builder {
94    #[staticmethod]
95    #[pyo3(signature = (**kwargs))]
96    fn build(kwargs: Option<&Bound<'_, PyDict>>) -> PyResult<Plugin> {
97        let args = BuilderArgs::from_kwargs(kwargs)?;
98
99        let mut builder = plugin::Builder::new();
100        if let Some(args) = args {
101            builder = args.apply_to_builder(builder);
102        }
103
104        let plugin = Plugin::new(Box::new(move || Box::new(builder.build())));
105        Ok(plugin)
106    }
107}
108
109/// See also: [tauri_plugin_updater]
110#[pymodule(submodule, gil_used = false)]
111pub mod updater {
112    #[pymodule_export]
113    pub use super::Builder;
114
115    pub use super::BuilderArgs;
116}