tauri_plugin_cache/
lib.rs

1use tauri::{
2    plugin::{Builder, TauriPlugin},
3    Manager, Runtime,
4};
5
6pub use models::*;
7
8#[cfg(desktop)]
9mod desktop;
10#[cfg(mobile)]
11mod mobile;
12
13mod commands;
14mod error;
15mod models;
16
17pub use error::{Error, Result};
18
19#[cfg(desktop)]
20use desktop::Cache;
21#[cfg(mobile)]
22use mobile::Cache;
23
24/// Extensions to [`tauri::App`], [`tauri::AppHandle`] and [`tauri::Window`] to access the cache APIs.
25pub trait CacheExt<R: Runtime> {
26    fn cache(&self) -> &Cache<R>;
27}
28
29impl<R: Runtime, T: Manager<R>> crate::CacheExt<R> for T {
30    fn cache(&self) -> &Cache<R> {
31        self.state::<Cache<R>>().inner()
32    }
33}
34
35/// Initializes the plugin.
36pub fn init<R: Runtime>() -> TauriPlugin<R> {
37    // Default config
38    let config = CacheConfig::default();
39    init_with_config(config)
40}
41
42/// Initializes the plugin with custom configuration.
43pub fn init_with_config<R: Runtime>(config: CacheConfig) -> TauriPlugin<R> {
44    // Clone config for use in the closure
45    let config_clone = config.clone();
46
47    Builder::new("cache")
48        .invoke_handler(tauri::generate_handler![
49            commands::set,
50            commands::get,
51            commands::has,
52            commands::remove,
53            commands::clear,
54            commands::stats
55        ])
56        .setup(move |app, api| {
57            // Provide the config manually to the desktop implementation
58            #[cfg(desktop)]
59            let cache = {
60                // Always start from app's cache directory
61                let base_cache_dir = app.path().app_cache_dir().map_err(|e| {
62                    crate::Error::Cache(format!("Failed to get app cache directory: {}", e))
63                })?;
64
65                // If custom subdirectory is specified, append it to the app cache directory path
66                let cache_dir = if let Some(custom_dir) = config_clone.cache_dir.as_deref() {
67                    let custom_path = std::path::PathBuf::from(custom_dir);
68                    if custom_path.is_absolute() {
69                        // Instead of absolute path, take only the last component
70                        let path_components: Vec<_> = custom_path
71                            .components()
72                            .filter(|c| !c.as_os_str().is_empty())
73                            .collect();
74
75                        if let Some(last_component) = path_components.last() {
76                            base_cache_dir.join(last_component.as_os_str())
77                        } else {
78                            base_cache_dir
79                        }
80                    } else {
81                        // Add as a relative path
82                        base_cache_dir.join(custom_dir)
83                    }
84                } else {
85                    base_cache_dir
86                };
87
88                // Create the cache directory if it doesn't exist
89                std::fs::create_dir_all(&cache_dir).map_err(|e| {
90                    crate::Error::Cache(format!("Failed to create cache directory: {}", e))
91                })?;
92
93                // Determine the cache file name
94                let cache_file_name = config_clone
95                    .cache_file_name
96                    .as_deref()
97                    .unwrap_or("tauri_cache.json");
98                let cache_file_path = cache_dir.join(cache_file_name);
99
100                // Get the default compression settings
101                let default_compression = config_clone.default_compression.unwrap_or(true);
102                let compression_level = config_clone.compression_level;
103                let compression_threshold = config_clone.compression_threshold;
104                let compression_method = config_clone.compression_method;
105
106                // Initialize the cache with cleanup interval
107                let mut cache = desktop::init_with_config(
108                    app,
109                    api,
110                    cache_file_path,
111                    config_clone.cleanup_interval.unwrap_or(60),
112                )?;
113
114                // Initialize with compression settings
115                cache.init_with_config(
116                    default_compression,
117                    compression_level,
118                    compression_threshold,
119                    compression_method,
120                );
121                cache
122            };
123
124            #[cfg(mobile)]
125            let cache = {
126                // Always start from app's cache directory
127                let base_cache_dir = app.path().app_cache_dir().map_err(|e| {
128                    crate::Error::Cache(format!("Failed to get app cache directory: {}", e))
129                })?;
130
131                // If custom subdirectory is specified, append it to the app cache directory path
132                let cache_dir = if let Some(custom_dir) = config_clone.cache_dir.as_deref() {
133                    let custom_path = std::path::PathBuf::from(custom_dir);
134                    if custom_path.is_absolute() {
135                        // Instead of absolute path, take only the last component
136                        let path_components: Vec<_> = custom_path
137                            .components()
138                            .filter(|c| !c.as_os_str().is_empty())
139                            .collect();
140
141                        if let Some(last_component) = path_components.last() {
142                            base_cache_dir.join(last_component.as_os_str())
143                        } else {
144                            base_cache_dir
145                        }
146                    } else {
147                        // Add as a relative path
148                        base_cache_dir.join(custom_dir)
149                    }
150                } else {
151                    base_cache_dir
152                };
153
154                // Create the cache directory if it doesn't exist
155                std::fs::create_dir_all(&cache_dir).map_err(|e| {
156                    crate::Error::Cache(format!("Failed to create cache directory: {}", e))
157                })?;
158
159                // Determine the cache file name
160                let cache_file_name = config_clone
161                    .cache_file_name
162                    .as_deref()
163                    .unwrap_or("tauri_cache.json");
164                let cache_file_path = cache_dir.join(cache_file_name);
165
166                // Get the default compression settings
167                let default_compression = config_clone.default_compression.unwrap_or(true);
168                let compression_level = config_clone.compression_level;
169                let compression_threshold = config_clone.compression_threshold;
170                let compression_method = config_clone.compression_method;
171
172                // Initialize the cache with cleanup interval
173                let mut cache = mobile::init_with_config(
174                    app,
175                    api,
176                    cache_file_path,
177                    config_clone.cleanup_interval.unwrap_or(60),
178                )?;
179
180                // Initialize with compression settings
181                cache.init_with_config(
182                    default_compression,
183                    compression_level,
184                    compression_threshold,
185                    compression_method,
186                );
187                cache
188            };
189
190            app.manage(cache);
191            Ok(())
192        })
193        .build()
194}