diff --git a/examples/test/src-tauri/src/main.rs b/examples/test/src-tauri/src/main.rs index d367b50..afccf34 100644 --- a/examples/test/src-tauri/src/main.rs +++ b/examples/test/src-tauri/src/main.rs @@ -5,7 +5,7 @@ use std::sync::atomic::{AtomicBool, Ordering}; -use tauri::{State, Manager}; +use tauri::{Manager, State}; struct Received(AtomicBool); // Learn more about Tauri commands at https://tauri.app/v1/guides/features/command @@ -28,7 +28,10 @@ fn main() { let app_handle = app.handle(); app.listen_global("foo", move |_| { - app_handle.state::().0.store(true, Ordering::Relaxed); + app_handle + .state::() + .0 + .store(true, Ordering::Relaxed); }); Ok(()) diff --git a/examples/test/src/app.rs b/examples/test/src/app.rs index 7ce0760..5ed8b4d 100644 --- a/examples/test/src/app.rs +++ b/examples/test/src/app.rs @@ -31,4 +31,4 @@ pub async fn get_tauri_version() -> anyhow::Result<()> { ensure!(version.pre.is_empty()); Ok(()) -} \ No newline at end of file +} diff --git a/examples/test/src/clipboard.rs b/examples/test/src/clipboard.rs index e84c521..816b459 100644 --- a/examples/test/src/clipboard.rs +++ b/examples/test/src/clipboard.rs @@ -9,4 +9,4 @@ pub async fn test() -> anyhow::Result<()> { ensure!(text == Some("foobar".to_string())); Ok(()) -} \ No newline at end of file +} diff --git a/examples/test/src/event.rs b/examples/test/src/event.rs index 7c207a4..4b76306 100644 --- a/examples/test/src/event.rs +++ b/examples/test/src/event.rs @@ -4,7 +4,9 @@ use tauri_sys::{event, tauri}; pub async fn emit() -> anyhow::Result<()> { event::emit("foo", &"bar").await; - ensure!(tauri::invoke::<_, bool>("verify_receive", &()).await.unwrap()); + ensure!(tauri::invoke::<_, bool>("verify_receive", &()) + .await + .unwrap()); Ok(()) -} \ No newline at end of file +} diff --git a/examples/test/src/main.rs b/examples/test/src/main.rs index 83aed19..8931580 100644 --- a/examples/test/src/main.rs +++ b/examples/test/src/main.rs @@ -18,7 +18,9 @@ async fn exit_with_error(e: String) { e: String, } - tauri_sys::tauri::invoke::<_, ()>("exit_with_error", &Args { e }).await.unwrap(); + tauri_sys::tauri::invoke::<_, ()>("exit_with_error", &Args { e }) + .await + .unwrap(); } #[derive(Props)] diff --git a/examples/test/src/window.rs b/examples/test/src/window.rs index 0954ea5..5de1cca 100644 --- a/examples/test/src/window.rs +++ b/examples/test/src/window.rs @@ -10,4 +10,4 @@ pub async fn create_window() -> anyhow::Result<()> { win.close().await; Ok(()) -} \ No newline at end of file +} diff --git a/src/app.rs b/src/app.rs index fae2cfb..6107110 100644 --- a/src/app.rs +++ b/src/app.rs @@ -1,5 +1,7 @@ use semver::Version; +use crate::Error; + /// Gets the application name. /// /// # Example @@ -9,8 +11,10 @@ use semver::Version; /// const appName = await getName(); /// ``` #[inline(always)] -pub async fn get_name() -> String { - inner::getName().await.as_string().unwrap() +pub async fn get_name() -> crate::Result { + let js_val = inner::getName().await.map_err(Error::Other)?; + + Ok(serde_wasm_bindgen::from_value(js_val)?) } /// Gets the application version. @@ -23,8 +27,10 @@ pub async fn get_name() -> String { /// let version = get_version().await; /// ``` #[inline(always)] -pub async fn get_version() -> Version { - Version::parse(&inner::getVersion().await.as_string().unwrap()).unwrap() +pub async fn get_version() -> crate::Result { + let js_val = inner::getVersion().await.map_err(Error::Other)?; + + Ok(serde_wasm_bindgen::from_value(js_val)?) } /// Gets the Tauri version. @@ -37,8 +43,10 @@ pub async fn get_version() -> Version { /// let version = get_tauri_version().await; /// ``` #[inline(always)] -pub async fn get_tauri_version() -> Version { - Version::parse(&inner::getTauriVersion().await.as_string().unwrap()).unwrap() +pub async fn get_tauri_version() -> crate::Result { + let js_val = inner::getTauriVersion().await.map_err(Error::Other)?; + + Ok(serde_wasm_bindgen::from_value(js_val)?) } /// Shows the application on macOS. This function does not automatically focuses any app window. @@ -51,8 +59,8 @@ pub async fn get_tauri_version() -> Version { /// show().await; /// ``` #[inline(always)] -pub async fn show() { - inner::show().await; +pub async fn show() -> crate::Result<()> { + inner::show().await.map_err(Error::Other) } /// Hides the application on macOS. @@ -65,8 +73,8 @@ pub async fn show() { /// hide().await; /// ``` #[inline(always)] -pub async fn hide() { - inner::hide().await; +pub async fn hide() -> crate::Result<()> { + inner::hide().await.map_err(Error::Other) } mod inner { @@ -74,10 +82,15 @@ mod inner { #[wasm_bindgen(module = "/dist/app.js")] extern "C" { - pub async fn getName() -> JsValue; - pub async fn getTauriVersion() -> JsValue; - pub async fn getVersion() -> JsValue; - pub async fn hide(); - pub async fn show(); + #[wasm_bindgen(catch)] + pub async fn getName() -> Result; + #[wasm_bindgen(catch)] + pub async fn getTauriVersion() -> Result; + #[wasm_bindgen(catch)] + pub async fn getVersion() -> Result; + #[wasm_bindgen(catch)] + pub async fn hide() -> Result<(), JsValue>; + #[wasm_bindgen(catch)] + pub async fn show() -> Result<(), JsValue>; } } diff --git a/src/clipboard.rs b/src/clipboard.rs index a716929..04155f4 100644 --- a/src/clipboard.rs +++ b/src/clipboard.rs @@ -1,3 +1,5 @@ +use crate::Error; + /// Gets the clipboard content as plain text. /// /// # Example @@ -8,8 +10,10 @@ /// let clipboard_text = read_text().await; /// ``` #[inline(always)] -pub async fn read_text() -> Option { - inner::readText().await.as_string() +pub async fn read_text() -> crate::Result { + let js_val = inner::readText().await.map_err(Error::Other)?; + + Ok(serde_wasm_bindgen::from_value(js_val)?) } /// Writes plain text to the clipboard. @@ -25,8 +29,8 @@ pub async fn read_text() -> Option { /// /// @returns A promise indicating the success or failure of the operation. #[inline(always)] -pub async fn write_text(text: &str) { - inner::writeText(text).await +pub async fn write_text(text: &str) -> crate::Result<()> { + inner::writeText(text).await.map_err(Error::Other) } mod inner { @@ -34,7 +38,9 @@ mod inner { #[wasm_bindgen(module = "/dist/clipboard.js")] extern "C" { - pub async fn readText() -> JsValue; - pub async fn writeText(text: &str); + #[wasm_bindgen(catch)] + pub async fn readText() -> Result; + #[wasm_bindgen(catch)] + pub async fn writeText(text: &str) -> Result<(), JsValue>; } } diff --git a/src/event.rs b/src/event.rs index 37cdb0f..fb89b77 100644 --- a/src/event.rs +++ b/src/event.rs @@ -3,6 +3,8 @@ use std::fmt::Debug; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use wasm_bindgen::{prelude::Closure, JsValue}; +use crate::Error; + #[derive(Deserialize)] pub struct Event { /// Event name @@ -45,8 +47,10 @@ impl Debug for Event { /// /// @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`. #[inline(always)] -pub async fn emit(event: &str, payload: &T) { - inner::emit(event, serde_wasm_bindgen::to_value(payload).unwrap()).await +pub async fn emit(event: &str, payload: &T) -> crate::Result<()> { + inner::emit(event, serde_wasm_bindgen::to_value(payload)?) + .await + .map_err(Error::Other) } /// Listen to an event from the backend. @@ -70,7 +74,7 @@ pub async fn emit(event: &str, payload: &T) { /// /// Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted. #[inline(always)] -pub async fn listen(event: &str, mut handler: H) -> impl FnOnce() +pub async fn listen(event: &str, mut handler: H) -> crate::Result where T: DeserializeOwned, H: FnMut(Event) + 'static, @@ -79,14 +83,14 @@ where (handler)(serde_wasm_bindgen::from_value(raw).unwrap()) }); - let unlisten = inner::listen(event, &closure).await; + let unlisten = inner::listen(event, &closure).await.map_err(Error::Other)?; closure.forget(); let unlisten = js_sys::Function::from(unlisten); - move || { + Ok(move || { unlisten.call0(&wasm_bindgen::JsValue::NULL).unwrap(); - } + }) } /// Listen to an one-off event from the backend. @@ -115,7 +119,7 @@ where /// /// Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted. #[inline(always)] -pub async fn once(event: &str, mut handler: H) -> impl FnOnce() +pub async fn once(event: &str, mut handler: H) -> crate::Result where T: DeserializeOwned, H: FnMut(Event) + 'static, @@ -124,14 +128,14 @@ where (handler)(serde_wasm_bindgen::from_value(raw).unwrap()) }); - let unlisten = inner::once(event, &closure).await; + let unlisten = inner::once(event, &closure).await.map_err(Error::Other)?; closure.forget(); let unlisten = js_sys::Function::from(unlisten); - move || { + Ok(move || { unlisten.call0(&wasm_bindgen::JsValue::NULL).unwrap(); - } + }) } mod inner { @@ -142,8 +146,17 @@ mod inner { #[wasm_bindgen(module = "/dist/event.js")] extern "C" { - pub async fn emit(event: &str, payload: JsValue); - pub async fn listen(event: &str, handler: &Closure) -> JsValue; - pub async fn once(event: &str, handler: &Closure) -> JsValue; + #[wasm_bindgen(catch)] + pub async fn emit(event: &str, payload: JsValue) -> Result<(), JsValue>; + #[wasm_bindgen(catch)] + pub async fn listen( + event: &str, + handler: &Closure, + ) -> Result; + #[wasm_bindgen(catch)] + pub async fn once( + event: &str, + handler: &Closure, + ) -> Result; } } diff --git a/src/lib.rs b/src/lib.rs index f65d708..780ee6f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,17 +8,23 @@ pub mod clipboard; pub mod event; #[cfg(feature = "mocks")] pub mod mocks; +#[cfg(feature = "process")] +pub mod process; #[cfg(feature = "tauri")] pub mod tauri; #[cfg(feature = "window")] pub mod window; -#[cfg(feature = "process")] -pub mod process; #[derive(Debug, thiserror::Error)] pub enum Error { #[error(transparent)] Serde(#[from] serde_wasm_bindgen::Error), + #[error("Unknown Theme \"{0}\". Expected one of \"light\",\"dark\"")] + UnknownTheme(String), + #[error("Invalid Url {0}")] + InvalidUrl(#[from] url::ParseError), + #[error("Invalid Version {0}")] + InvalidVersion(#[from] semver::Error), #[error("{0:?}")] Other(JsValue), } diff --git a/src/tauri.rs b/src/tauri.rs index ad43df3..98654e6 100644 --- a/src/tauri.rs +++ b/src/tauri.rs @@ -1,6 +1,8 @@ use serde::{de::DeserializeOwned, Serialize}; use url::Url; +use crate::Error; + /// Convert a device file path to an URL that can be loaded by the webview. /// Note that `asset:` and `https://asset.localhost` must be added to [`tauri.security.csp`](https://tauri.app/v1/api/config/#securityconfig.csp) in `tauri.conf.json`. /// Example CSP value: `"csp": "default-src 'self'; img-src 'self' asset: https://asset.localhost"` to use the asset protocol on image sources. @@ -36,14 +38,12 @@ use url::Url; /// /// @return the URL that can be used as source on the webview. #[inline(always)] -pub async fn convert_file_src(file_path: &str, protocol: Option<&str>) -> Url { - Url::parse( - &inner::convertFileSrc(file_path, protocol) - .await - .as_string() - .unwrap(), - ) - .unwrap() +pub async fn convert_file_src(file_path: &str, protocol: Option<&str>) -> crate::Result { + let js_val = inner::convertFileSrc(file_path, protocol) + .await + .map_err(Error::Other)?; + + Ok(serde_wasm_bindgen::from_value(js_val)?) } /// Sends a message to the backend. @@ -66,9 +66,10 @@ pub async fn convert_file_src(file_path: &str, protocol: Option<&str>) -> Url { /// @return A promise resolving or rejecting to the backend response. #[inline(always)] pub async fn invoke(cmd: &str, args: &A) -> crate::Result { - let res = inner::invoke(cmd, serde_wasm_bindgen::to_value(args).unwrap()).await; + let raw = inner::invoke(cmd, serde_wasm_bindgen::to_value(args)?) + .await + .map_err(crate::Error::Other)?; - let raw = res.map_err(crate::Error::Other)?; serde_wasm_bindgen::from_value(raw).map_err(Into::into) } @@ -77,14 +78,18 @@ pub async fn invoke(cmd: &str, args: &A) -> c /// /// @return A unique identifier associated with the callback function. #[inline(always)] -pub async fn transform_callback(callback: &dyn Fn(T), once: bool) -> f64 { - inner::transformCallback( +pub async fn transform_callback( + callback: &dyn Fn(T), + once: bool, +) -> crate::Result { + let js_val = inner::transformCallback( &|raw| callback(serde_wasm_bindgen::from_value(raw).unwrap()), once, ) .await - .as_f64() - .unwrap() + .map_err(Error::Other)?; + + Ok(serde_wasm_bindgen::from_value(js_val)?) } mod inner { @@ -92,9 +97,17 @@ mod inner { #[wasm_bindgen(module = "/dist/tauri.js")] extern "C" { - pub async fn convertFileSrc(filePath: &str, protocol: Option<&str>) -> JsValue; + #[wasm_bindgen(catch)] + pub async fn convertFileSrc( + filePath: &str, + protocol: Option<&str>, + ) -> Result; #[wasm_bindgen(catch)] pub async fn invoke(cmd: &str, args: JsValue) -> Result; - pub async fn transformCallback(callback: &dyn Fn(JsValue), once: bool) -> JsValue; + #[wasm_bindgen(catch)] + pub async fn transformCallback( + callback: &dyn Fn(JsValue), + once: bool, + ) -> Result; } } diff --git a/src/window.rs b/src/window.rs index 3bec133..d0a88bd 100644 --- a/src/window.rs +++ b/src/window.rs @@ -1,4 +1,4 @@ -use crate::event::Event; +use crate::{event::Event, Error}; use serde::{de::DeserializeOwned, Serialize}; use std::fmt::Display; use wasm_bindgen::{prelude::Closure, JsCast, JsValue}; @@ -135,192 +135,279 @@ impl WebviewWindow { self.0.label() } - pub async fn scale_factor(&self) -> f64 { - self.0.scaleFactor().await.as_f64().unwrap() + pub async fn scale_factor(&self) -> crate::Result { + let js_val = self.0.scaleFactor().await.map_err(Error::Other)?; + + Ok(serde_wasm_bindgen::from_value(js_val)?) } - pub async fn inner_position(&self) -> PhysicalPosition { - PhysicalPosition(self.0.innerPosition().await.unchecked_into()) + pub async fn inner_position(&self) -> crate::Result { + Ok(PhysicalPosition( + self.0 + .innerPosition() + .await + .map_err(Error::Other)? + .unchecked_into(), + )) } - pub async fn outer_position(&self) -> PhysicalPosition { - PhysicalPosition(self.0.outerPosition().await.unchecked_into()) + pub async fn outer_position(&self) -> crate::Result { + Ok(PhysicalPosition( + self.0 + .outerPosition() + .await + .map_err(Error::Other)? + .unchecked_into(), + )) } - pub async fn inner_size(&self) -> PhysicalSize { - PhysicalSize(self.0.innerSize().await.unchecked_into()) + pub async fn inner_size(&self) -> crate::Result { + Ok(PhysicalSize( + self.0 + .innerSize() + .await + .map_err(Error::Other)? + .unchecked_into(), + )) } - pub async fn outer_size(&self) -> PhysicalSize { - PhysicalSize(self.0.outerSize().await.unchecked_into()) + pub async fn outer_size(&self) -> crate::Result { + Ok(PhysicalSize( + self.0 + .outerSize() + .await + .map_err(Error::Other)? + .unchecked_into(), + )) } - pub async fn is_fullscreen(&self) -> bool { - self.0.isFullscreen().await.as_bool().unwrap() + pub async fn is_fullscreen(&self) -> crate::Result { + let js_val = self.0.isFullscreen().await.map_err(Error::Other)?; + + Ok(serde_wasm_bindgen::from_value(js_val)?) } - pub async fn is_maximized(&self) -> bool { - self.0.isMaximized().await.as_bool().unwrap() + pub async fn is_maximized(&self) -> crate::Result { + let js_val = self.0.isMaximized().await.map_err(Error::Other)?; + + Ok(serde_wasm_bindgen::from_value(js_val)?) } - pub async fn is_decorated(&self) -> bool { - self.0.isDecorated().await.as_bool().unwrap() + pub async fn is_decorated(&self) -> crate::Result { + let js_val = self.0.isDecorated().await.map_err(Error::Other)?; + + Ok(serde_wasm_bindgen::from_value(js_val)?) } - pub async fn is_resizable(&self) -> bool { - self.0.isResizable().await.as_bool().unwrap() + pub async fn is_resizable(&self) -> crate::Result { + let js_val = self.0.isResizable().await.map_err(Error::Other)?; + + Ok(serde_wasm_bindgen::from_value(js_val)?) } - pub async fn is_visible(&self) -> bool { - self.0.isVisible().await.as_bool().unwrap() + pub async fn is_visible(&self) -> crate::Result { + let js_val = self.0.isVisible().await.map_err(Error::Other)?; + + Ok(serde_wasm_bindgen::from_value(js_val)?) } - pub async fn theme(&self) -> Theme { - match self.0.theme().await.as_string().unwrap().as_str() { - "light" => Theme::Light, - "dark" => Theme::Dark, - _ => panic!("Unknown theme"), + pub async fn theme(&self) -> crate::Result { + let js_val = self.0.theme().await.map_err(Error::Other)?; + + let str = serde_wasm_bindgen::from_value::(js_val)?; + + match str.as_str() { + "light" => Ok(Theme::Light), + "dark" => Ok(Theme::Dark), + _ => Err(Error::UnknownTheme(str)), } } - pub async fn center(&self) { - self.0.center().await; + pub async fn center(&self) -> crate::Result<()> { + self.0.center().await.map_err(Error::Other) } - pub async fn request_user_attention(&self, request_type: UserAttentionType) { - self.0.requestUserAttention(request_type as u32).await; + pub async fn request_user_attention( + &self, + request_type: UserAttentionType, + ) -> crate::Result<()> { + self.0 + .requestUserAttention(request_type as u32) + .await + .map_err(Error::Other) } - pub async fn set_resizable(&self, resizable: bool) { - self.0.setResizable(resizable).await; + pub async fn set_resizable(&self, resizable: bool) -> crate::Result<()> { + self.0.setResizable(resizable).await.map_err(Error::Other) } - pub async fn set_title(&self, title: impl AsRef) { - self.0.setTitle(title.as_ref()).await; + pub async fn set_title(&self, title: impl AsRef) -> crate::Result<()> { + self.0.setTitle(title.as_ref()).await.map_err(Error::Other) } - pub async fn maximize(&self) { - self.0.maximize().await; + pub async fn maximize(&self) -> crate::Result<()> { + self.0.maximize().await.map_err(Error::Other) } - pub async fn unmaximize(&self) { - self.0.unmaximize().await; + pub async fn unmaximize(&self) -> crate::Result<()> { + self.0.unmaximize().await.map_err(Error::Other) } - pub async fn toggle_maximize(&self) { - self.0.toggleMaximize().await; + pub async fn toggle_maximize(&self) -> crate::Result<()> { + self.0.toggleMaximize().await.map_err(Error::Other) } - pub async fn minimize(&self) { - self.0.minimize().await; + pub async fn minimize(&self) -> crate::Result<()> { + self.0.minimize().await.map_err(Error::Other) } - pub async fn unminimize(&self) { - self.0.unminimize().await; + pub async fn unminimize(&self) -> crate::Result<()> { + self.0.unminimize().await.map_err(Error::Other) } - pub async fn show(&self) { - self.0.show().await; + pub async fn show(&self) -> crate::Result<()> { + self.0.show().await.map_err(Error::Other) } - pub async fn hide(&self) { - self.0.hide().await; + pub async fn hide(&self) -> crate::Result<()> { + self.0.hide().await.map_err(Error::Other) } - pub async fn close(&self) { - self.0.close().await; + pub async fn close(&self) -> crate::Result<()> { + self.0.close().await.map_err(Error::Other) } - pub async fn set_decorations(&self, decorations: bool) { - self.0.setDecorations(decorations).await; + pub async fn set_decorations(&self, decorations: bool) -> crate::Result<()> { + self.0 + .setDecorations(decorations) + .await + .map_err(Error::Other) } - pub async fn set_always_on_top(&self, always_on_top: bool) { - self.0.setAlwaysOnTop(always_on_top).await; + pub async fn set_always_on_top(&self, always_on_top: bool) -> crate::Result<()> { + self.0 + .setAlwaysOnTop(always_on_top) + .await + .map_err(Error::Other) } - pub async fn set_size(&self, size: Size) { + pub async fn set_size(&self, size: Size) -> crate::Result<()> { match size { - Size::Physical(size) => self.0.setSizePhysical(size.0).await, - Size::Logical(size) => self.0.setSizeLogical(size.0).await, - }; - } - - pub async fn set_min_size(&self, size: Option) { - match size { - None => self.0.setMinSizePhysical(None).await, - Some(Size::Physical(size)) => self.0.setMinSizePhysical(Some(size.0)).await, - Some(Size::Logical(size)) => self.0.setMinSizeLogical(Some(size.0)).await, + Size::Physical(size) => self.0.setSizePhysical(size.0).await.map_err(Error::Other), + Size::Logical(size) => self.0.setSizeLogical(size.0).await.map_err(Error::Other), } } - pub async fn set_max_size(&self, size: Option) { + pub async fn set_min_size(&self, size: Option) -> crate::Result<()> { match size { - None => self.0.setMaxSizePhysical(None).await, - Some(Size::Physical(size)) => self.0.setMaxSizePhysical(Some(size.0)).await, - Some(Size::Logical(size)) => self.0.setMaxSizeLogical(Some(size.0)).await, + None => self.0.setMinSizePhysical(None).await.map_err(Error::Other), + Some(Size::Physical(size)) => self + .0 + .setMinSizePhysical(Some(size.0)) + .await + .map_err(Error::Other), + Some(Size::Logical(size)) => self + .0 + .setMinSizeLogical(Some(size.0)) + .await + .map_err(Error::Other), } } - pub async fn set_position(&self, position: Position) { + pub async fn set_max_size(&self, size: Option) -> crate::Result<()> { + match size { + None => self.0.setMaxSizePhysical(None).await.map_err(Error::Other), + Some(Size::Physical(size)) => self + .0 + .setMaxSizePhysical(Some(size.0)) + .await + .map_err(Error::Other), + Some(Size::Logical(size)) => self + .0 + .setMaxSizeLogical(Some(size.0)) + .await + .map_err(Error::Other), + } + } + + pub async fn set_position(&self, position: Position) -> crate::Result<()> { match position { - Position::Physical(pos) => self.0.setPositionPhysical(pos.0).await, - Position::Logical(pos) => self.0.setPositionLogical(pos.0).await, + Position::Physical(pos) => self + .0 + .setPositionPhysical(pos.0) + .await + .map_err(Error::Other), + Position::Logical(pos) => self.0.setPositionLogical(pos.0).await.map_err(Error::Other), } } - pub async fn set_fullscreen(&self, fullscreen: bool) { - self.0.setFullscreen(fullscreen).await; + pub async fn set_fullscreen(&self, fullscreen: bool) -> crate::Result<()> { + self.0.setFullscreen(fullscreen).await.map_err(Error::Other) } - pub async fn set_focus(&self) { - self.0.setFocus().await; + pub async fn set_focus(&self) -> crate::Result<()> { + self.0.setFocus().await.map_err(Error::Other) } - pub async fn set_icon(&self, icon: &[u8]) { - self.0.setIcon(icon).await; + pub async fn set_icon(&self, icon: &[u8]) -> crate::Result<()> { + self.0.setIcon(icon).await.map_err(Error::Other) } - pub async fn set_skip_taskbar(&self, skip: bool) { - self.0.setSkipTaskbar(skip).await; + pub async fn set_skip_taskbar(&self, skip: bool) -> crate::Result<()> { + self.0.setSkipTaskbar(skip).await.map_err(Error::Other) } - pub async fn set_cursor_grab(&self, grab: bool) { - self.0.setCursorGrab(grab).await; + pub async fn set_cursor_grab(&self, grab: bool) -> crate::Result<()> { + self.0.setCursorGrab(grab).await.map_err(Error::Other) } - pub async fn set_cursor_visible(&self, visible: bool) { - self.0.setCursorVisible(visible).await; + pub async fn set_cursor_visible(&self, visible: bool) -> crate::Result<()> { + self.0.setCursorVisible(visible).await.map_err(Error::Other) } - pub async fn set_cursor_icon(&self, icon: CursorIcon) { - self.0.setCursorIcon(&icon.to_string()).await; + pub async fn set_cursor_icon(&self, icon: CursorIcon) -> crate::Result<()> { + self.0 + .setCursorIcon(&icon.to_string()) + .await + .map_err(Error::Other) } - pub async fn set_cursor_position(&self, position: Position) { + pub async fn set_cursor_position(&self, position: Position) -> crate::Result<()> { match position { - Position::Physical(pos) => self.0.setCursorPositionPhysical(pos.0).await, - Position::Logical(pos) => self.0.setCursorPositionLogical(pos.0).await, + Position::Physical(pos) => self + .0 + .setCursorPositionPhysical(pos.0) + .await + .map_err(Error::Other), + Position::Logical(pos) => self + .0 + .setCursorPositionLogical(pos.0) + .await + .map_err(Error::Other), } } - pub async fn set_ignore_cursor_events(&self, ignore: bool) { - self.0.setIgnoreCursorEvents(ignore).await; + pub async fn set_ignore_cursor_events(&self, ignore: bool) -> crate::Result<()> { + self.0 + .setIgnoreCursorEvents(ignore) + .await + .map_err(Error::Other) } - pub async fn start_dragging(&self) { - self.0.startDragging().await; + pub async fn start_dragging(&self) -> crate::Result<()> { + self.0.startDragging().await.map_err(Error::Other) } #[inline(always)] - pub async fn emit(&self, event: &str, payload: &T) { + pub async fn emit(&self, event: &str, payload: &T) -> crate::Result<()> { self.0 .emit(event, serde_wasm_bindgen::to_value(payload).unwrap()) - .await; + .await + .map_err(Error::Other) } #[inline(always)] - pub async fn listen(&self, event: &str, mut handler: H) -> impl FnOnce() + pub async fn listen(&self, event: &str, mut handler: H) -> crate::Result where T: DeserializeOwned, H: FnMut(Event) + 'static, @@ -329,18 +416,18 @@ impl WebviewWindow { (handler)(serde_wasm_bindgen::from_value(raw).unwrap()) }); - let unlisten = self.0.listen(event, &closure).await; + let unlisten = self.0.listen(event, &closure).await.map_err(Error::Other)?; closure.forget(); let unlisten = js_sys::Function::from(unlisten); - move || { + Ok(move || { unlisten.call0(&wasm_bindgen::JsValue::NULL).unwrap(); - } + }) } #[inline(always)] - pub async fn once(&self, event: &str, mut handler: H) -> impl FnOnce() + pub async fn once(&self, event: &str, mut handler: H) -> crate::Result where T: DeserializeOwned, H: FnMut(Event) + 'static, @@ -349,14 +436,14 @@ impl WebviewWindow { (handler)(serde_wasm_bindgen::from_value(raw).unwrap()) }); - let unlisten = self.0.once(event, &closure).await; + let unlisten = self.0.once(event, &closure).await.map_err(Error::Other)?; closure.forget(); let unlisten = js_sys::Function::from(unlisten); - move || { + Ok(move || { unlisten.call0(&wasm_bindgen::JsValue::NULL).unwrap(); - } + }) } } @@ -529,7 +616,7 @@ impl Iterator for AvailableMonitors { pub async fn available_monitors() -> AvailableMonitors { AvailableMonitors { idx: 0, - array: inner::availableMonitors().await.unchecked_into() + array: inner::availableMonitors().await.unchecked_into(), } } @@ -613,20 +700,24 @@ mod inner { pub type WebviewWindowHandle; #[wasm_bindgen(constructor)] pub fn new(label: &str) -> WebviewWindowHandle; - #[wasm_bindgen(method)] + #[wasm_bindgen(method, catch)] pub async fn listen( this: &WebviewWindowHandle, event: &str, handler: &Closure, - ) -> JsValue; - #[wasm_bindgen(method)] + ) -> Result; + #[wasm_bindgen(method, catch)] pub async fn once( this: &WebviewWindowHandle, event: &str, handler: &Closure, - ) -> JsValue; - #[wasm_bindgen(method)] - pub async fn emit(this: &WebviewWindowHandle, event: &str, payload: JsValue); + ) -> Result; + #[wasm_bindgen(method, catch)] + pub async fn emit( + this: &WebviewWindowHandle, + event: &str, + payload: JsValue, + ) -> Result<(), JsValue>; } #[wasm_bindgen(module = "/dist/window.js")] @@ -638,94 +729,130 @@ mod inner { pub fn new(label: &str) -> WindowManager; #[wasm_bindgen(method, getter)] pub fn label(this: &WindowManager) -> String; - #[wasm_bindgen(method)] - pub async fn scaleFactor(this: &WindowManager) -> JsValue; - #[wasm_bindgen(method)] - pub async fn innerPosition(this: &WindowManager) -> JsValue; - #[wasm_bindgen(method)] - pub async fn outerPosition(this: &WindowManager) -> JsValue; - #[wasm_bindgen(method)] - pub async fn innerSize(this: &WindowManager) -> JsValue; - #[wasm_bindgen(method)] - pub async fn outerSize(this: &WindowManager) -> JsValue; - #[wasm_bindgen(method)] - pub async fn isFullscreen(this: &WindowManager) -> JsValue; - #[wasm_bindgen(method)] - pub async fn isMaximized(this: &WindowManager) -> JsValue; - #[wasm_bindgen(method)] - pub async fn isDecorated(this: &WindowManager) -> JsValue; - #[wasm_bindgen(method)] - pub async fn isResizable(this: &WindowManager) -> JsValue; - #[wasm_bindgen(method)] - pub async fn isVisible(this: &WindowManager) -> JsValue; - #[wasm_bindgen(method)] - pub async fn theme(this: &WindowManager) -> JsValue; - #[wasm_bindgen(method)] - pub async fn center(this: &WindowManager); - #[wasm_bindgen(method)] - pub async fn requestUserAttention(this: &WindowManager, requestType: u32); - #[wasm_bindgen(method)] - pub async fn setResizable(this: &WindowManager, resizable: bool); - #[wasm_bindgen(method)] - pub async fn setTitle(this: &WindowManager, title: &str); - #[wasm_bindgen(method)] - pub async fn maximize(this: &WindowManager); - #[wasm_bindgen(method)] - pub async fn unmaximize(this: &WindowManager); - #[wasm_bindgen(method)] - pub async fn toggleMaximize(this: &WindowManager); - #[wasm_bindgen(method)] - pub async fn minimize(this: &WindowManager); - #[wasm_bindgen(method)] - pub async fn unminimize(this: &WindowManager); - #[wasm_bindgen(method)] - pub async fn show(this: &WindowManager); - #[wasm_bindgen(method)] - pub async fn hide(this: &WindowManager); - #[wasm_bindgen(method)] - pub async fn close(this: &WindowManager); - #[wasm_bindgen(method)] - pub async fn setDecorations(this: &WindowManager, decorations: bool); - #[wasm_bindgen(method)] - pub async fn setAlwaysOnTop(this: &WindowManager, alwaysOnTop: bool); - #[wasm_bindgen(method, js_name = setSize)] - pub async fn setSizePhysical(this: &WindowManager, size: PhysicalSize); - #[wasm_bindgen(method, js_name = setSize)] - pub async fn setSizeLogical(this: &WindowManager, size: LogicalSize); - #[wasm_bindgen(method, js_name = setMinSize)] - pub async fn setMinSizePhysical(this: &WindowManager, size: Option); - #[wasm_bindgen(method, js_name = setMinSize)] - pub async fn setMinSizeLogical(this: &WindowManager, size: Option); - #[wasm_bindgen(method, js_name = setMaxSize)] - pub async fn setMaxSizePhysical(this: &WindowManager, size: Option); - #[wasm_bindgen(method, js_name = setMinSize)] - pub async fn setMaxSizeLogical(this: &WindowManager, size: Option); - #[wasm_bindgen(method, js_name = setPosition)] - pub async fn setPositionPhysical(this: &WindowManager, position: PhysicalPosition); - #[wasm_bindgen(method, js_name = setPosition)] - pub async fn setPositionLogical(this: &WindowManager, position: LogicalPosition); - #[wasm_bindgen(method)] - pub async fn setFullscreen(this: &WindowManager, fullscreen: bool); - #[wasm_bindgen(method)] - pub async fn setFocus(this: &WindowManager); - #[wasm_bindgen(method)] - pub async fn setIcon(this: &WindowManager, icon: &[u8]); - #[wasm_bindgen(method)] - pub async fn setSkipTaskbar(this: &WindowManager, skip: bool); - #[wasm_bindgen(method)] - pub async fn setCursorGrab(this: &WindowManager, grab: bool); - #[wasm_bindgen(method)] - pub async fn setCursorVisible(this: &WindowManager, visible: bool); - #[wasm_bindgen(method)] - pub async fn setCursorIcon(this: &WindowManager, icon: &str); - #[wasm_bindgen(method, js_name = setCursorPosition)] - pub async fn setCursorPositionPhysical(this: &WindowManager, position: PhysicalPosition); - #[wasm_bindgen(method, js_name = setCursorPosition)] - pub async fn setCursorPositionLogical(this: &WindowManager, position: LogicalPosition); - #[wasm_bindgen(method)] - pub async fn setIgnoreCursorEvents(this: &WindowManager, ignore: bool); - #[wasm_bindgen(method)] - pub async fn startDragging(this: &WindowManager); + #[wasm_bindgen(method, catch)] + pub async fn scaleFactor(this: &WindowManager) -> Result; + #[wasm_bindgen(method, catch)] + pub async fn innerPosition(this: &WindowManager) -> Result; + #[wasm_bindgen(method, catch)] + pub async fn outerPosition(this: &WindowManager) -> Result; + #[wasm_bindgen(method, catch)] + pub async fn innerSize(this: &WindowManager) -> Result; + #[wasm_bindgen(method, catch)] + pub async fn outerSize(this: &WindowManager) -> Result; + #[wasm_bindgen(method, catch)] + pub async fn isFullscreen(this: &WindowManager) -> Result; + #[wasm_bindgen(method, catch)] + pub async fn isMaximized(this: &WindowManager) -> Result; + #[wasm_bindgen(method, catch)] + pub async fn isDecorated(this: &WindowManager) -> Result; + #[wasm_bindgen(method, catch)] + pub async fn isResizable(this: &WindowManager) -> Result; + #[wasm_bindgen(method, catch)] + pub async fn isVisible(this: &WindowManager) -> Result; + #[wasm_bindgen(method, catch)] + pub async fn theme(this: &WindowManager) -> Result; + #[wasm_bindgen(method, catch)] + pub async fn center(this: &WindowManager) -> Result<(), JsValue>; + #[wasm_bindgen(method, catch)] + pub async fn requestUserAttention( + this: &WindowManager, + requestType: u32, + ) -> Result<(), JsValue>; + #[wasm_bindgen(method, catch)] + pub async fn setResizable(this: &WindowManager, resizable: bool) -> Result<(), JsValue>; + #[wasm_bindgen(method, catch)] + pub async fn setTitle(this: &WindowManager, title: &str) -> Result<(), JsValue>; + #[wasm_bindgen(method, catch)] + pub async fn maximize(this: &WindowManager) -> Result<(), JsValue>; + #[wasm_bindgen(method, catch)] + pub async fn unmaximize(this: &WindowManager) -> Result<(), JsValue>; + #[wasm_bindgen(method, catch)] + pub async fn toggleMaximize(this: &WindowManager) -> Result<(), JsValue>; + #[wasm_bindgen(method, catch)] + pub async fn minimize(this: &WindowManager) -> Result<(), JsValue>; + #[wasm_bindgen(method, catch)] + pub async fn unminimize(this: &WindowManager) -> Result<(), JsValue>; + #[wasm_bindgen(method, catch)] + pub async fn show(this: &WindowManager) -> Result<(), JsValue>; + #[wasm_bindgen(method, catch)] + pub async fn hide(this: &WindowManager) -> Result<(), JsValue>; + #[wasm_bindgen(method, catch)] + pub async fn close(this: &WindowManager) -> Result<(), JsValue>; + #[wasm_bindgen(method, catch)] + pub async fn setDecorations(this: &WindowManager, decorations: bool) + -> Result<(), JsValue>; + #[wasm_bindgen(method, catch)] + pub async fn setAlwaysOnTop(this: &WindowManager, alwaysOnTop: bool) + -> Result<(), JsValue>; + #[wasm_bindgen(method, js_name = setSize, catch)] + pub async fn setSizePhysical( + this: &WindowManager, + size: PhysicalSize, + ) -> Result<(), JsValue>; + #[wasm_bindgen(method, js_name = setSize, catch)] + pub async fn setSizeLogical(this: &WindowManager, size: LogicalSize) + -> Result<(), JsValue>; + #[wasm_bindgen(method, js_name = setMinSize, catch)] + pub async fn setMinSizePhysical( + this: &WindowManager, + size: Option, + ) -> Result<(), JsValue>; + #[wasm_bindgen(method, js_name = setMinSize, catch)] + pub async fn setMinSizeLogical( + this: &WindowManager, + size: Option, + ) -> Result<(), JsValue>; + #[wasm_bindgen(method, js_name = setMaxSize, catch)] + pub async fn setMaxSizePhysical( + this: &WindowManager, + size: Option, + ) -> Result<(), JsValue>; + #[wasm_bindgen(method, js_name = setMinSize, catch)] + pub async fn setMaxSizeLogical( + this: &WindowManager, + size: Option, + ) -> Result<(), JsValue>; + #[wasm_bindgen(method, js_name = setPosition, catch)] + pub async fn setPositionPhysical( + this: &WindowManager, + position: PhysicalPosition, + ) -> Result<(), JsValue>; + #[wasm_bindgen(method, js_name = setPosition, catch)] + pub async fn setPositionLogical( + this: &WindowManager, + position: LogicalPosition, + ) -> Result<(), JsValue>; + #[wasm_bindgen(method, catch)] + pub async fn setFullscreen(this: &WindowManager, fullscreen: bool) -> Result<(), JsValue>; + #[wasm_bindgen(method, catch)] + pub async fn setFocus(this: &WindowManager) -> Result<(), JsValue>; + #[wasm_bindgen(method, catch)] + pub async fn setIcon(this: &WindowManager, icon: &[u8]) -> Result<(), JsValue>; + #[wasm_bindgen(method, catch)] + pub async fn setSkipTaskbar(this: &WindowManager, skip: bool) -> Result<(), JsValue>; + #[wasm_bindgen(method, catch)] + pub async fn setCursorGrab(this: &WindowManager, grab: bool) -> Result<(), JsValue>; + #[wasm_bindgen(method, catch)] + pub async fn setCursorVisible(this: &WindowManager, visible: bool) -> Result<(), JsValue>; + #[wasm_bindgen(method, catch)] + pub async fn setCursorIcon(this: &WindowManager, icon: &str) -> Result<(), JsValue>; + #[wasm_bindgen(method, js_name = setCursorPosition, catch)] + pub async fn setCursorPositionPhysical( + this: &WindowManager, + position: PhysicalPosition, + ) -> Result<(), JsValue>; + #[wasm_bindgen(method, js_name = setCursorPosition, catch)] + pub async fn setCursorPositionLogical( + this: &WindowManager, + position: LogicalPosition, + ) -> Result<(), JsValue>; + #[wasm_bindgen(method, catch)] + pub async fn setIgnoreCursorEvents( + this: &WindowManager, + ignore: bool, + ) -> Result<(), JsValue>; + #[wasm_bindgen(method, catch)] + pub async fn startDragging(this: &WindowManager) -> Result<(), JsValue>; } #[wasm_bindgen(module = "/dist/window.js")]