From d1f650edd347771430f96290748ab364b205bfbb Mon Sep 17 00:00:00 2001 From: Lucas Fernandes Nogueira Date: Thu, 20 May 2021 10:40:18 -0300 Subject: [PATCH] chore(docs): improve `manage` API examples on interior mutability (#1875) --- core/tauri/src/app.rs | 35 ++++++++++++++++++++++++++ examples/state/src-tauri/src/main.rs | 37 +++++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/core/tauri/src/app.rs b/core/tauri/src/app.rs index a45784336..3452c6c76 100644 --- a/core/tauri/src/app.rs +++ b/core/tauri/src/app.rs @@ -377,6 +377,40 @@ where /// /// Panics if state of type `T` is already being managed. /// + /// # Mutability + /// + /// Since the managed state is global and must be [`Send`] + [`Sync`], mutations can only happen through interior mutability: + /// + /// ```rust,ignore + /// use std::{collections::HashMap, sync::Mutex}; + /// use tauri::State; + /// // here we use Mutex to achieve interior mutability + /// struct Storage(Mutex>); + /// struct Connection; + /// struct DbConnection(Mutex>); + /// + /// #[tauri::command] + /// fn connect(connection: State) { + /// // initialize the connection, mutating the state with interior mutability + /// *connection.0.lock().unwrap() = Some(Connection {}); + /// } + /// + /// #[tauri::command] + /// fn storage_insert(key: u64, value: String, storage: State) { + /// // mutate the storage behind the Mutex + /// storage.0.lock().unwrap().insert(key, value); + /// } + /// + /// fn main() { + /// Builder::default() + /// .manage(Storage(Default::default())) + /// .manage(DbConnection(Default::default())) + /// .invoke_handler(tauri::generate_handler![connect, storage_insert]) + /// .run(tauri::generate_context!()) + /// .expect("error while running tauri application"); + /// } + /// ``` + /// /// # Example /// /// ```rust,ignore @@ -399,6 +433,7 @@ where /// tauri::Builder::default() /// .manage(MyInt(10)) /// .manage(MyString("Hello, managed state!".to_string())) + /// .invoke_handler(tauri::generate_handler![int_command, string_command]) /// .run(tauri::generate_context!()) /// .expect("error while running tauri application"); /// } diff --git a/examples/state/src-tauri/src/main.rs b/examples/state/src-tauri/src/main.rs index 902ba5c07..09b5e73bf 100644 --- a/examples/state/src-tauri/src/main.rs +++ b/examples/state/src-tauri/src/main.rs @@ -22,6 +22,37 @@ struct Counter(AtomicUsize); #[derive(Default)] struct Database(Arc>>); +struct Client; + +impl Client { + fn send(&self) {} +} + +#[derive(Default)] +struct Connection(Mutex>); + +#[tauri::command] +fn connect(connection: State) { + *connection.0.lock().unwrap() = Some(Client {}); +} + +#[tauri::command] +fn disconnect(connection: State) { + // drop the connection + *connection.0.lock().unwrap() = None; +} + +#[tauri::command] +fn connection_send(connection: State) { + connection + .0 + .lock() + .unwrap() + .as_ref() + .expect("connection not initialize; use the `connect` command first") + .send(); +} + #[tauri::command] fn increment_counter(counter: State) -> usize { counter.0.fetch_add(1, Ordering::Relaxed) + 1 @@ -41,10 +72,14 @@ fn main() { tauri::Builder::default() .manage(Counter(AtomicUsize::new(0))) .manage(Database(Default::default())) + .manage(Connection(Default::default())) .invoke_handler(tauri::generate_handler![ increment_counter, db_insert, - db_read + db_read, + connect, + disconnect, + connection_send ]) .run(tauri::generate_context!()) .expect("error while running tauri application");