tauri_plugin_config_manager/
lib.rs1use notify::{
2 event::{DataChange, ModifyKind},
3 EventKind, RecommendedWatcher, Watcher,
4};
5use std::sync::Mutex;
6use tauri::{
7 plugin::{Builder, TauriPlugin},
8 Emitter, Manager, Runtime,
9};
10
11mod commands;
12#[cfg(desktop)]
13mod desktop;
14mod error;
15
16pub use error::{Error, Result};
17
18#[cfg(desktop)]
19use desktop::ConfigManager;
20
21pub trait ConfigManagerExt<R: Runtime> {
23 fn config_manager(&self) -> &ConfigManager<R>;
24}
25
26impl<R: Runtime, T: Manager<R>> crate::ConfigManagerExt<R> for T {
27 fn config_manager(&self) -> &ConfigManager<R> {
28 self.state::<ConfigManager<R>>().inner()
29 }
30}
31
32fn watch_config_file<R: Runtime + 'static>(
33 app: &tauri::AppHandle<R>,
34) -> Box<dyn FnMut(notify::Result<notify::Event>) + Send + 'static> {
35 let app_handle = app.clone();
36 Box::new(move |res: notify::Result<notify::Event>| {
37 let Ok(event) = res else {
38 if let Err(e) = res {
39 eprintln!(
40 "[Config Watcher Callback] Error watching config file: {:?}",
41 e
42 );
43 }
44 return;
45 };
46
47 if matches!(
48 event.kind,
49 EventKind::Modify(ModifyKind::Data(DataChange::Any))
50 ) {
51 app_handle.emit("config-changed", ()).unwrap_or_else(|e| {
52 eprintln!(
53 "[Config Watcher Callback] Failed to emit config-changed event: {}",
54 e
55 );
56 });
57 }
58 })
59}
60
61pub fn init<R: Runtime>() -> TauriPlugin<R> {
63 Builder::new("config-manager")
64 .invoke_handler(tauri::generate_handler![
65 commands::read_config,
66 commands::write_config
67 ])
68 .setup(|app, api| {
69 let config_manager = desktop::init(app, api)?;
70 let config_path = config_manager.config_path().to_path_buf();
71 app.manage(config_manager);
72
73 let app_handle_for_watcher = app.clone();
74 let event_handler = watch_config_file(&app_handle_for_watcher);
75
76 let mut watcher: RecommendedWatcher = notify::recommended_watcher(event_handler)
77 .map_err(|e| {
78 Error::Other(format!("Cannot create watcher for config file: {}", e))
79 })?;
80
81 watcher
82 .watch(config_path.as_path(), notify::RecursiveMode::Recursive)
83 .map_err(|e| {
84 Error::Other(format!(
85 "Failed to watch config file {}: {}",
86 config_path.display(),
87 e
88 ))
89 })?;
90
91 app.manage(Mutex::new(watcher));
92
93 Ok(())
94 })
95 .build()
96}