From 2ea56cf21d61ed2bc2039efe194a3145043c6871 Mon Sep 17 00:00:00 2001 From: chip Date: Mon, 5 Apr 2021 09:33:07 -0700 Subject: [PATCH] refactor(tauri): add some better docs for Tag (#1425) --- tauri/src/endpoints/event.rs | 5 ++-- tauri/src/endpoints/window.rs | 11 ++++--- tauri/src/runtime/mod.rs | 3 +- tauri/src/runtime/tag.rs | 55 +++++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 7 deletions(-) diff --git a/tauri/src/endpoints/event.rs b/tauri/src/endpoints/event.rs index c860f14fb..1acbe8c44 100644 --- a/tauri/src/endpoints/event.rs +++ b/tauri/src/endpoints/event.rs @@ -40,13 +40,14 @@ impl Cmd { window_label, payload, } => { + // Panic if the user's `Tag` type decided to return an error while parsing. let e: M::Event = event .parse() - .unwrap_or_else(|_| panic!("todo: invalid event str")); + .unwrap_or_else(|_| panic!("Event module received unhandled event: {}", event)); let window_label: Option = window_label.map(|l| { l.parse() - .unwrap_or_else(|_| panic!("todo: invalid window label")) + .unwrap_or_else(|_| panic!("Event module recieved unhandled window: {}", l)) }); // dispatch the event to Rust listeners diff --git a/tauri/src/endpoints/window.rs b/tauri/src/endpoints/window.rs index 420648900..fb087a2f5 100644 --- a/tauri/src/endpoints/window.rs +++ b/tauri/src/endpoints/window.rs @@ -110,10 +110,13 @@ impl Cmd { )); #[cfg(window_create)] { - let label: M::Label = options - .label - .parse() - .unwrap_or_else(|_| panic!("todo: label parsing")); + // Panic if the user's `Tag` type decided to return an error while parsing. + let label: M::Label = options.label.parse().unwrap_or_else(|_| { + panic!( + "Window module received unknown window label: {}", + options.label + ) + }); let url = options.url.clone(); let pending = PendingWindow::new(WindowConfig(options), label.clone(), url); diff --git a/tauri/src/runtime/mod.rs b/tauri/src/runtime/mod.rs index 2a17ba824..a3db6106a 100644 --- a/tauri/src/runtime/mod.rs +++ b/tauri/src/runtime/mod.rs @@ -2,7 +2,6 @@ use crate::{ api::{assets::Assets, config::Config}, event::{Event, EventHandler}, runtime::{ - tag::Tag, webview::{Attributes, AttributesPrivate, Icon, WindowConfig}, window::{DetachedWindow, PendingWindow, Window}, }, @@ -17,6 +16,8 @@ pub(crate) mod tag; pub(crate) mod webview; pub(crate) mod window; +pub use self::tag::Tag; + /// Important configurable items required by Tauri. pub struct Context { /// The config the application was prepared with. diff --git a/tauri/src/runtime/tag.rs b/tauri/src/runtime/tag.rs index 5791233fd..d98b1aeac 100644 --- a/tauri/src/runtime/tag.rs +++ b/tauri/src/runtime/tag.rs @@ -17,6 +17,61 @@ use std::{ /// across thread boundaries, although some of those constraints may relax in the future. /// /// The simplest type that fits all these requirements is a [`String`](std::string::String). +/// +/// # Handling Errors +/// +/// Because we leave it up to the type to implement [`FromStr`], if an error is returned during +/// parsing then Tauri will [`panic!`](std::panic) with the string it failed to parse. +/// +/// To avoid Tauri panicking during the application runtime, have your type be able to handle +/// unknown events and never return an error in [`FromStr`]. Then it will be up to your own code +/// to handle the unknown event. +/// +/// # Example +/// +/// ``` +/// use std::fmt; +/// use std::str::FromStr; +/// +/// #[derive(Debug, Clone, Hash, Eq, PartialEq)] +/// enum Event { +/// Foo, +/// Bar, +/// Unknown(String), +/// } +/// +/// impl fmt::Display for Event { +/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +/// f.write_str(match self { +/// Self::Foo => "foo", +/// Self::Bar => "bar", +/// Self::Unknown(s) => &s +/// }) +/// } +/// } +/// +/// impl FromStr for Event { +/// type Err = std::convert::Infallible; +/// +/// fn from_str(s: &str) -> Result { +/// Ok(match s { +/// "foo" => Self::Foo, +/// "bar" => Self::Bar, +/// other => Self::Unknown(other.to_string()) +/// }) +/// } +/// } +/// +/// // safe to unwrap because we know it's infallible due to our FromStr implementation. +/// let event: Event = "tauri://file-drop".parse().unwrap(); +/// +/// // show that this event type can be represented as a Tag, a requirement for using it in Tauri. +/// fn is_file_drop(tag: impl tauri::runtime::Tag) { +/// assert_eq!("tauri://file-drop", tag.to_string()); +/// } +/// +/// is_file_drop(event); +/// ``` pub trait Tag: Hash + Eq + FromStr + Display + Debug + Clone + Send + Sync + 'static {} /// Automatically implement [`Tag`] for all types that fit the requirements.