Преглед изворни кода

refactor(core): more bounds for better errors from #1623 (#1632)

chip пре 4 година
родитељ
комит
a755d23e1b

+ 19 - 1
.changes/simplify-tag-label-usage.md

@@ -2,4 +2,22 @@
 "tauri": patch
 ---
 
-Simplify usage of app event and window label types.
+Simplify usage of app event and window label types. The following functions now
+accept references the `Tag` can be borrowed as. This means an `&str` can now be
+accepted for functions like `Window::emit`. This is a breaking change for the
+following items, which now need to take a reference. Additionally, type inference
+for `&"event".into()` will no longer work, but `&"event".to_string()` will. The
+solution for this is to now just pass `"event"` because `Borrow<str>` is implemented
+for the default event type `String`.
+
+* **Breaking:** `Window::emit` now accepts `Borrow` for the event.
+* **Breaking:** `Window::emit_others` now accepts `Borrow` for the event
+* **Breaking:** `Window::trigger` now accepts `Borrow` for the event.
+* **Breaking:** `Manager::emit_all` now accepts `Borrow` for the event.
+* **Breaking:** `Manager::emit_to` now accepts `Borrow` for both the event and window label.
+* **Breaking:** `Manager::trigger_global` now accepts `Borrow` for the event.
+* **Breaking:** `Manager::get_window` now accepts `Borrow` for the window label.
+* _(internal):_ `trait tauri::runtime::tag::TagRef` helper for accepting tag references.
+  Any time you want to accept a tag reference, that trait will handle requiring the reference
+  to have all the necessary bounds, and generate errors when the exposed function doesn't
+  set a bound like `P::Event: Borrow<E>`.

+ 7 - 3
core/tauri/src/event.rs

@@ -192,10 +192,14 @@ impl<Event: Tag, Window: Tag> Listeners<Event, Window> {
   }
 
   /// Triggers the given global event with its payload.
-  pub(crate) fn trigger<E>(&self, event: &E, window: Option<Window>, payload: Option<String>)
-  where
-    E: TagRef<Event> + ?Sized,
+  pub(crate) fn trigger<E: ?Sized>(
+    &self,
+    event: &E,
+    window: Option<Window>,
+    payload: Option<String>,
+  ) where
     Event: Borrow<E>,
+    E: TagRef<Event>,
   {
     let mut maybe_pending = false;
     match self.inner.handlers.try_lock() {

+ 12 - 9
core/tauri/src/lib.rs

@@ -139,24 +139,27 @@ pub trait Manager<P: Params>: sealed::ManagerBase<P> {
   }
 
   /// Emits a event to all windows.
-  fn emit_all<E, S>(&self, event: &E, payload: Option<S>) -> Result<()>
+  fn emit_all<E: ?Sized, S>(&self, event: &E, payload: Option<S>) -> Result<()>
   where
-    E: TagRef<P::Event> + ?Sized,
+    P::Event: Borrow<E>,
+    E: TagRef<P::Event>,
     S: Serialize + Clone,
   {
     self.manager().emit_filter(event, payload, |_| true)
   }
 
   /// Emits an event to a window with the specified label.
-  fn emit_to<E, L, S: Serialize + Clone>(
+  fn emit_to<E: ?Sized, L: ?Sized, S: Serialize + Clone>(
     &self,
     label: &L,
     event: &E,
     payload: Option<S>,
   ) -> Result<()>
   where
-    L: TagRef<P::Label> + ?Sized,
-    E: TagRef<P::Event> + ?Sized,
+    P::Label: Borrow<L>,
+    P::Event: Borrow<E>,
+    L: TagRef<P::Label>,
+    E: TagRef<P::Event>,
   {
     self
       .manager()
@@ -193,10 +196,10 @@ pub trait Manager<P: Params>: sealed::ManagerBase<P> {
   }
 
   /// Trigger a global event.
-  fn trigger_global<E>(&self, event: &E, data: Option<String>)
+  fn trigger_global<E: ?Sized>(&self, event: &E, data: Option<String>)
   where
-    E: TagRef<P::Event> + ?Sized,
     P::Event: Borrow<E>,
+    E: TagRef<P::Event>,
   {
     self.manager().trigger(event, None, data)
   }
@@ -207,10 +210,10 @@ pub trait Manager<P: Params>: sealed::ManagerBase<P> {
   }
 
   /// Fetch a single window from the manager.
-  fn get_window<L>(&self, label: &L) -> Option<Window<P>>
+  fn get_window<L: ?Sized>(&self, label: &L) -> Option<Window<P>>
   where
-    L: TagRef<P::Label> + ?Sized,
     P::Label: Borrow<L>,
+    L: TagRef<P::Label>,
   {
     self.manager().get_window(label)
   }

+ 12 - 6
core/tauri/src/runtime/manager.rs

@@ -493,9 +493,15 @@ impl<P: Params> WindowManager<P> {
     window
   }
 
-  pub fn emit_filter<E, S, F>(&self, event: &E, payload: Option<S>, filter: F) -> crate::Result<()>
+  pub fn emit_filter<E: ?Sized, S, F>(
+    &self,
+    event: &E,
+    payload: Option<S>,
+    filter: F,
+  ) -> crate::Result<()>
   where
-    E: TagRef<P::Event> + ?Sized,
+    P::Event: Borrow<E>,
+    E: TagRef<P::Event>,
     S: Serialize + Clone,
     F: Fn(&Window<P>) -> bool,
   {
@@ -519,10 +525,10 @@ impl<P: Params> WindowManager<P> {
     self.inner.listeners.unlisten(handler_id)
   }
 
-  pub fn trigger<E>(&self, event: &E, window: Option<P::Label>, data: Option<String>)
+  pub fn trigger<E: ?Sized>(&self, event: &E, window: Option<P::Label>, data: Option<String>)
   where
-    E: TagRef<P::Event> + ?Sized,
     P::Event: Borrow<E>,
+    E: TagRef<P::Event>,
   {
     self.inner.listeners.trigger(event, window, data)
   }
@@ -578,10 +584,10 @@ impl<P: Params> WindowManager<P> {
       .remove(&uuid)
   }
 
-  pub fn get_window<L>(&self, label: &L) -> Option<Window<P>>
+  pub fn get_window<L: ?Sized>(&self, label: &L) -> Option<Window<P>>
   where
-    L: TagRef<P::Label> + ?Sized,
     P::Label: Borrow<L>,
+    L: TagRef<P::Label>,
   {
     self.windows_lock().get(label).cloned()
   }

+ 9 - 3
core/tauri/src/runtime/tag.rs

@@ -91,11 +91,17 @@ impl<T, E: Debug> Tag for T where
 /// * [`ToOwned`] to make sure we can clone it into the owned tag in specific cases.
 /// * [`PartialEq`] so that we can compare refs to the owned tags easily.
 /// * [`Hash`] + [`Eq`] because we want to be able to use a ref as a key to internal hashmaps.
-pub trait TagRef<T: Tag>: Display + ToOwned<Owned = T> + PartialEq<T> + Eq + Hash {}
+pub trait TagRef<T: Tag>: Display + ToOwned<Owned = T> + PartialEq<T> + Eq + Hash
+where
+  T: std::borrow::Borrow<Self>,
+{
+}
 
 /// Automatically implement [`TagRef`] for all types that fit the requirements.
-impl<T: Tag, R> TagRef<T> for R where
-  R: Display + ToOwned<Owned = T> + PartialEq<T> + Eq + Hash + ?Sized
+impl<T: Tag, R> TagRef<T> for R
+where
+  T: std::borrow::Borrow<R>,
+  R: Display + ToOwned<Owned = T> + PartialEq<T> + Eq + Hash + ?Sized,
 {
 }
 

+ 18 - 11
core/tauri/src/runtime/window.rs

@@ -196,9 +196,14 @@ pub(crate) mod export {
       &self.window.label
     }
 
-    pub(crate) fn emit_internal<E, S>(&self, event: &E, payload: Option<S>) -> crate::Result<()>
+    pub(crate) fn emit_internal<E: ?Sized, S>(
+      &self,
+      event: &E,
+      payload: Option<S>,
+    ) -> crate::Result<()>
     where
-      E: TagRef<P::Event> + ?Sized,
+      P::Event: Borrow<E>,
+      E: TagRef<P::Event>,
       S: Serialize,
     {
       let js_payload = match payload {
@@ -218,20 +223,22 @@ pub(crate) mod export {
     }
 
     /// Emits an event to the current window.
-    pub fn emit<E, S>(&self, event: &E, payload: Option<S>) -> crate::Result<()>
+    pub fn emit<E: ?Sized, S>(&self, event: &E, payload: Option<S>) -> crate::Result<()>
     where
-      E: TagRef<P::Event> + ?Sized,
+      P::Event: Borrow<E>,
+      E: TagRef<P::Event>,
       S: Serialize,
     {
       self.emit_internal(event, payload)
     }
 
     /// Emits an event on all windows except this one.
-    pub fn emit_others<E: TagRef<P::Event> + ?Sized, S: Serialize + Clone>(
-      &self,
-      event: &E,
-      payload: Option<S>,
-    ) -> crate::Result<()> {
+    pub fn emit_others<E: ?Sized, S>(&self, event: &E, payload: Option<S>) -> crate::Result<()>
+    where
+      P::Event: Borrow<E>,
+      E: TagRef<P::Event>,
+      S: Serialize + Clone,
+    {
       self.manager.emit_filter(event, payload, |w| w != self)
     }
 
@@ -254,10 +261,10 @@ pub(crate) mod export {
     }
 
     /// Triggers an event on this window.
-    pub fn trigger<E>(&self, event: &E, data: Option<String>)
+    pub fn trigger<E: ?Sized>(&self, event: &E, data: Option<String>)
     where
-      E: TagRef<P::Event> + ?Sized,
       P::Event: Borrow<E>,
+      E: TagRef<P::Event>,
     {
       let label = self.window.label.clone();
       self.manager.trigger(event, Some(label), data)