diff --git a/plugins/store/src/lib.rs b/plugins/store/src/lib.rs index 1cb95cad..cabd6b6a 100644 --- a/plugins/store/src/lib.rs +++ b/plugins/store/src/lib.rs @@ -111,7 +111,7 @@ async fn create_store( serialize_fn_name, deserialize_fn_name, )?; - let (_, rid) = builder.create_inner()?; + let (_, rid) = builder.create_new().build_inner()?; Ok(rid) } @@ -132,7 +132,7 @@ async fn load( serialize_fn_name, deserialize_fn_name, )?; - let (_, rid) = builder.load_inner()?; + let (_, rid) = builder.build_inner()?; Ok(rid) } @@ -258,24 +258,6 @@ pub trait StoreExt { /// }); /// ``` fn store(&self, path: impl AsRef) -> Result>>; - /// Create a store with default settings. - /// - /// If the store is already loaded you must check with [`Self::get_store`] or prefer [`Self::store`] - /// as it will return `Err(Error::AlreadyExists)`. - /// - /// # Examples - /// - /// ``` - /// use tauri_plugin_store::StoreExt; - /// - /// tauri::Builder::default() - /// .plugin(tauri_plugin_store::Builder::default().build()) - /// .setup(|app| { - /// let store = app.create_store("my-store")?; - /// Ok(()) - /// }); - /// ``` - fn create_store(&self, path: impl AsRef) -> Result>>; /// Get a store builder. /// /// The builder can be used to configure the store. @@ -290,7 +272,7 @@ pub trait StoreExt { /// tauri::Builder::default() /// .plugin(tauri_plugin_store::Builder::default().build()) /// .setup(|app| { - /// let store = app.store_builder("users.json").auto_save(Duration::from_secs(1)).load()?; + /// let store = app.store_builder("users.json").auto_save(Duration::from_secs(1)).build()?; /// Ok(()) /// }); /// ``` @@ -326,11 +308,7 @@ pub trait StoreExt { impl> StoreExt for T { fn store(&self, path: impl AsRef) -> Result>> { - StoreBuilder::new(self.app_handle(), path).load() - } - - fn create_store(&self, path: impl AsRef) -> Result>> { - StoreBuilder::new(self.app_handle(), path).create() + StoreBuilder::new(self.app_handle(), path).build() } fn store_builder(&self, path: impl AsRef) -> StoreBuilder { @@ -447,7 +425,7 @@ impl Builder { /// tauri::Builder::default() /// .plugin(tauri_plugin_store::Builder::default().build()) /// .setup(|app| { - /// let store = tauri_plugin_store::StoreBuilder::new(app, "store.bin").load()?; + /// let store = tauri_plugin_store::StoreBuilder::new(app, "store.bin").build()?; /// Ok(()) /// }); /// ``` diff --git a/plugins/store/src/store.rs b/plugins/store/src/store.rs index 2750bc01..9111aa2d 100644 --- a/plugins/store/src/store.rs +++ b/plugins/store/src/store.rs @@ -8,7 +8,7 @@ use std::{ collections::HashMap, fs, path::{Path, PathBuf}, - sync::{Arc, Mutex, MutexGuard}, + sync::{Arc, Mutex}, time::Duration, }; use tauri::{path::BaseDirectory, AppHandle, Emitter, Manager, Resource, ResourceId, Runtime}; @@ -38,6 +38,7 @@ pub struct StoreBuilder { serialize_fn: SerializeFn, deserialize_fn: DeserializeFn, auto_save: Option, + create_new: bool, } impl StoreBuilder { @@ -64,6 +65,7 @@ impl StoreBuilder { serialize_fn, deserialize_fn, auto_save: Some(Duration::from_millis(100)), + create_new: false, } } @@ -79,7 +81,7 @@ impl StoreBuilder { /// /// let store = tauri_plugin_store::StoreBuilder::new(app, "store.bin") /// .defaults(defaults) - /// .load()?; + /// .build()?; /// Ok(()) /// }); /// ``` @@ -97,7 +99,7 @@ impl StoreBuilder { /// .setup(|app| { /// let store = tauri_plugin_store::StoreBuilder::new(app, "store.bin") /// .default("foo".to_string(), "bar") - /// .load()?; + /// .build()?; /// Ok(()) /// }); /// ``` @@ -119,7 +121,7 @@ impl StoreBuilder { /// .setup(|app| { /// let store = tauri_plugin_store::StoreBuilder::new(app, "store.json") /// .serialize(|cache| serde_json::to_vec(&cache).map_err(Into::into)) - /// .load()?; + /// .build()?; /// Ok(()) /// }); /// ``` @@ -137,7 +139,7 @@ impl StoreBuilder { /// .setup(|app| { /// let store = tauri_plugin_store::StoreBuilder::new(app, "store.json") /// .deserialize(|bytes| serde_json::from_slice(&bytes).map_err(Into::into)) - /// .load()?; + /// .build()?; /// Ok(()) /// }); /// ``` @@ -155,7 +157,7 @@ impl StoreBuilder { /// .setup(|app| { /// let store = tauri_plugin_store::StoreBuilder::new(app, "store.json") /// .auto_save(std::time::Duration::from_millis(100)) - /// .load()?; + /// .build()?; /// Ok(()) /// }); /// ``` @@ -164,16 +166,25 @@ impl StoreBuilder { self } - /// Disable auto save on modified with a debounce duration + /// Disable auto save on modified with a debounce duration. pub fn disable_auto_save(mut self) -> Self { self.auto_save = None; self } - pub(crate) fn build_inner( - mut self, - mut stores: MutexGuard<'_, HashMap>, - ) -> crate::Result<(Arc>, ResourceId)> { + /// Force create a new store even if it already exists. + pub fn create_new(mut self) -> Self { + self.create_new = true; + self + } + + pub(crate) fn build_inner(mut self) -> crate::Result<(Arc>, ResourceId)> { + let stores = self.app.state::().stores.clone(); + let mut stores = stores.lock().unwrap(); + if let Some(rid) = stores.get(&self.path) { + return Ok((self.app.resources_table().get(*rid).unwrap(), *rid)); + } + if stores.contains_key(&self.path) { return Err(crate::Error::AlreadyExists(self.path)); } @@ -185,7 +196,10 @@ impl StoreBuilder { self.serialize_fn, self.deserialize_fn, ); - let _ = store_inner.load(); + + if !self.create_new { + let _ = store_inner.load(); + } let store = Store { auto_save: self.auto_save, @@ -200,64 +214,23 @@ impl StoreBuilder { Ok((store, rid)) } - /// Builds the [`Store`], also see [`build_or_existing`](Self::build_or_existing). - /// - /// This loads the store from disk and put the store in the app's resource table, - /// to remove it from the resource table, call [`Store::close_store`] - /// - /// # Errors - /// - /// If a store with this path is already in the resource table, - /// will return a [`crate::Error::AlreadyExists`] - /// - /// # Examples - /// ``` - /// tauri::Builder::default() - /// .plugin(tauri_plugin_store::Builder::default().build()) - /// .setup(|app| { - /// let store = tauri_plugin_store::StoreBuilder::new(app, "store.json").load()?; - /// Ok(()) - /// }); - /// ``` - pub fn create(self) -> crate::Result>> { - let (store, _) = self.create_inner()?; - Ok(store) - } - - pub(crate) fn create_inner(self) -> crate::Result<(Arc>, ResourceId)> { - let stores = self.app.state::().stores.clone(); - self.build_inner(stores.lock().unwrap()) - } - - /// Get the existing store with the same path or creates a new [`Store`]. + /// Load the existing store with the same path or creates a new [`Store`]. /// /// If a store with the same path has already been loaded its instance is returned. /// - /// See [`create`](Self::create) if you want to force create a new store in the path. - /// /// # Examples /// ``` /// tauri::Builder::default() /// .plugin(tauri_plugin_store::Builder::default().build()) /// .setup(|app| { - /// let store = tauri_plugin_store::StoreBuilder::new(app, "store.json").load(); + /// let store = tauri_plugin_store::StoreBuilder::new(app, "store.json").build(); /// Ok(()) /// }); /// ``` - pub fn load(self) -> crate::Result>> { - let (store, _) = self.load_inner()?; + pub fn build(self) -> crate::Result>> { + let (store, _) = self.build_inner()?; Ok(store) } - - pub(crate) fn load_inner(self) -> crate::Result<(Arc>, ResourceId)> { - let stores = self.app.state::().stores.clone(); - let stores_ = stores.lock().unwrap(); - if let Some(rid) = stores_.get(&self.path) { - return Ok((self.app.resources_table().get(*rid).unwrap(), *rid)); - } - - self.build_inner(stores_) - } } enum AutoSaveMessage {