tauri_plugin_telemetry/
builder.rs1use std::{panic::PanicHookInfo, sync::Arc};
2
3use tauri::{
4 Manager, RunEvent, Runtime,
5 plugin::{self, TauriPlugin},
6};
7
8use crate::{InitOptions, client::TelemetryClient, commands, config::Config};
9
10pub struct Builder {
12 app_key: String,
13 panic_hook: Option<PanicHook>,
14 options: InitOptions,
15}
16
17pub type PanicHook =
18 Box<dyn Fn(&TelemetryClient, &PanicHookInfo<'_>, String) + 'static + Sync + Send>;
19
20fn get_panic_message(info: &PanicHookInfo) -> String {
21 let payload = info.payload();
22 if let Some(s) = payload.downcast_ref::<&str>() {
23 return s.to_string();
24 } else if let Some(s) = payload.downcast_ref::<String>() {
25 return s.to_string();
26 }
27
28 format!("{:?}", payload)
29}
30
31impl Builder {
32 pub fn new(app_key: &str) -> Self {
34 Self {
35 app_key: app_key.into(),
36 panic_hook: None,
37 options: Default::default(),
38 }
39 }
40
41 pub fn with_options(mut self, opts: InitOptions) -> Self {
43 self.options = opts;
44 self
45 }
46
47 pub fn with_panic_hook(mut self, hook: PanicHook) -> Self {
49 self.panic_hook = Some(hook);
50 self
51 }
52
53 pub fn build<R: Runtime>(self) -> TauriPlugin<R> {
55 plugin::Builder::new("telemetry")
56 .invoke_handler(tauri::generate_handler![commands::track_event])
57 .setup(|app, _api| {
58 let cfg = Config::new(self.app_key, self.options);
59 let app_version = app.package_info().version.to_string();
60 let client = Arc::new(TelemetryClient::new(&cfg, app_version));
61
62 client.start_polling(cfg.flush_interval);
63
64 if let Some(hook) = self.panic_hook {
65 install_panic_hook(hook, client.clone());
66 }
67
68 app.manage(client);
69 Ok(())
70 })
71 .on_event(move |app, event| {
72 if let RunEvent::Exit = event {
73 let client = app.state::<Arc<TelemetryClient>>();
74 client.flush_blocking();
75 }
76 })
77 .build()
78 }
79}
80
81fn install_panic_hook(hook: PanicHook, client: Arc<TelemetryClient>) {
84 let default_panic = std::panic::take_hook();
85 std::panic::set_hook(Box::new(move |info| {
86 let msg = get_panic_message(info);
87 hook(&client, info, msg);
88 client.flush_blocking();
89 default_panic(info);
90 }));
91}