Procházet zdrojové kódy

chore(docs): improve `manage` API examples on interior mutability (#1875)

Lucas Fernandes Nogueira před 4 roky
rodič
revize
d1f650edd3
2 změnil soubory, kde provedl 71 přidání a 1 odebrání
  1. 35 0
      core/tauri/src/app.rs
  2. 36 1
      examples/state/src-tauri/src/main.rs

+ 35 - 0
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<HashMap<u64, String>>);
+  /// struct Connection;
+  /// struct DbConnection(Mutex<Option<Connection>>);
+  ///
+  /// #[tauri::command]
+  /// fn connect(connection: State<DbConnection>) {
+  ///   // 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<Storage>) {
+  ///   // 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");
   /// }

+ 36 - 1
examples/state/src-tauri/src/main.rs

@@ -22,6 +22,37 @@ struct Counter(AtomicUsize);
 #[derive(Default)]
 struct Database(Arc<Mutex<HashMap<String, String>>>);
 
+struct Client;
+
+impl Client {
+  fn send(&self) {}
+}
+
+#[derive(Default)]
+struct Connection(Mutex<Option<Client>>);
+
+#[tauri::command]
+fn connect(connection: State<Connection>) {
+  *connection.0.lock().unwrap() = Some(Client {});
+}
+
+#[tauri::command]
+fn disconnect(connection: State<Connection>) {
+  // drop the connection
+  *connection.0.lock().unwrap() = None;
+}
+
+#[tauri::command]
+fn connection_send(connection: State<Connection>) {
+  connection
+    .0
+    .lock()
+    .unwrap()
+    .as_ref()
+    .expect("connection not initialize; use the `connect` command first")
+    .send();
+}
+
 #[tauri::command]
 fn increment_counter(counter: State<Counter>) -> 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");