initial commit
This commit is contained in:
commit
c3e5b84282
54 changed files with 2009 additions and 0 deletions
83
src/app.rs
Normal file
83
src/app.rs
Normal file
|
@ -0,0 +1,83 @@
|
|||
use semver::Version;
|
||||
|
||||
/// Gets the application name.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```typescript
|
||||
/// import { getName } from '@tauri-apps/api/app';
|
||||
/// const appName = await getName();
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub async fn get_name() -> String {
|
||||
inner::getName().await.as_string().unwrap()
|
||||
}
|
||||
|
||||
/// Gets the application version.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use tauri_api::app::get_version;
|
||||
///
|
||||
/// let version = get_version().await;
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub async fn get_version() -> Version {
|
||||
Version::parse(&inner::getVersion().await.as_string().unwrap()).unwrap()
|
||||
}
|
||||
|
||||
/// Gets the Tauri version.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use tauri_app::app:get_tauri_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()
|
||||
}
|
||||
|
||||
/// Shows the application on macOS. This function does not automatically focuses any app window.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use tauri_api::app::show;
|
||||
///
|
||||
/// show().await;
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub async fn show() {
|
||||
inner::show().await;
|
||||
}
|
||||
|
||||
/// Hides the application on macOS.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use tauri_api::app::hide;
|
||||
///
|
||||
/// hide().await;
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub async fn hide() {
|
||||
inner::hide().await;
|
||||
}
|
||||
|
||||
mod inner {
|
||||
use wasm_bindgen::{prelude::wasm_bindgen, JsValue};
|
||||
|
||||
#[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();
|
||||
}
|
||||
}
|
40
src/clipboard.rs
Normal file
40
src/clipboard.rs
Normal file
|
@ -0,0 +1,40 @@
|
|||
/// Gets the clipboard content as plain text.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use tauri_api::clipboard::read_text;
|
||||
///
|
||||
/// let clipboard_text = read_text().await;
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub async fn read_text() -> Option<String> {
|
||||
inner::readText().await.as_string()
|
||||
}
|
||||
|
||||
/// Writes plain text to the clipboard.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use tauri_api::clipboard::{write_text, read_text};
|
||||
///
|
||||
/// write_text("Tauri is awesome!").await;
|
||||
/// assert_eq!(read_text().await, "Tauri is awesome!");
|
||||
/// ```
|
||||
///
|
||||
/// @returns A promise indicating the success or failure of the operation.
|
||||
#[inline(always)]
|
||||
pub async fn write_text(text: &str) {
|
||||
inner::writeText(text).await
|
||||
}
|
||||
|
||||
mod inner {
|
||||
use wasm_bindgen::{prelude::wasm_bindgen, JsValue};
|
||||
|
||||
#[wasm_bindgen(module = "/dist/clipboard.js")]
|
||||
extern "C" {
|
||||
pub async fn readText() -> JsValue;
|
||||
pub async fn writeText(text: &str);
|
||||
}
|
||||
}
|
134
src/event.rs
Normal file
134
src/event.rs
Normal file
|
@ -0,0 +1,134 @@
|
|||
use std::fmt::Debug;
|
||||
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Event<T> {
|
||||
/// Event name
|
||||
pub event: String,
|
||||
/// Event identifier used to unlisten
|
||||
pub id: u32,
|
||||
/// Event payload
|
||||
pub payload: T,
|
||||
/// The label of the window that emitted this event
|
||||
pub window_label: String,
|
||||
}
|
||||
|
||||
impl<T: Debug> Debug for Event<T> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("Event")
|
||||
.field("event", &self.event)
|
||||
.field("id", &self.id)
|
||||
.field("payload", &self.payload)
|
||||
.field("window_label", &self.window_label)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// Emits an event to the backend.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use tauri_api::event::emit;
|
||||
/// use serde::Serialize;
|
||||
///
|
||||
/// #[derive(Serialize)]
|
||||
/// struct Payload {
|
||||
/// logged_in: bool,
|
||||
/// token: String
|
||||
/// }
|
||||
///
|
||||
/// emit("frontend-loaded", &Payload { logged_in: true, token: "authToken" }).await;
|
||||
/// ```
|
||||
///
|
||||
/// @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.
|
||||
#[inline(always)]
|
||||
pub async fn emit<T: Serialize>(event: &str, payload: &T) {
|
||||
inner::emit(event, serde_wasm_bindgen::to_value(payload).unwrap()).await
|
||||
}
|
||||
|
||||
/// Listen to an event from the backend.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use tauri_api::event::{emit, listen};
|
||||
///
|
||||
/// const unlisten = listen::<String>("error", |event| {
|
||||
/// println!("Got error in window {}, payload: {}", event.window_label, event.payload);
|
||||
/// }).await;
|
||||
///
|
||||
/// // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
|
||||
/// unlisten();
|
||||
/// ```
|
||||
///
|
||||
/// @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.
|
||||
/// @param handler Event handler callback.
|
||||
/// @returns A promise resolving to a function to unlisten to the event.
|
||||
///
|
||||
/// 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<T: DeserializeOwned>(event: &str, handler: &dyn Fn(Event<T>)) -> impl FnOnce() {
|
||||
let unlisten = inner::listen(event, &|raw| {
|
||||
handler(serde_wasm_bindgen::from_value(raw).unwrap())
|
||||
})
|
||||
.await;
|
||||
|
||||
let unlisten = js_sys::Function::from(unlisten);
|
||||
move || {
|
||||
unlisten.call0(&wasm_bindgen::JsValue::NULL).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
/// Listen to an one-off event from the backend.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use tauri_api::event::once;
|
||||
/// use serde::Deserialize;
|
||||
///
|
||||
/// #[derive(Deserialize)]
|
||||
/// interface LoadedPayload {
|
||||
/// logged_in: bool,
|
||||
/// token: String
|
||||
/// }
|
||||
/// const unlisten = once::<LoadedPayload>("loaded", |event| {
|
||||
/// println!("App is loaded, loggedIn: {}, token: {}", event.payload.logged_in, event.payload.token);
|
||||
/// }).await;
|
||||
///
|
||||
/// // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
|
||||
/// unlisten();
|
||||
/// ```
|
||||
///
|
||||
/// @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.
|
||||
/// @returns A promise resolving to a function to unlisten to the event.
|
||||
///
|
||||
/// 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<T: DeserializeOwned>(
|
||||
event: &str,
|
||||
handler: &mut dyn FnMut(Event<T>),
|
||||
) -> impl FnOnce() {
|
||||
let unlisten = inner::once(event, &mut |raw| {
|
||||
handler(serde_wasm_bindgen::from_value(raw).unwrap())
|
||||
})
|
||||
.await;
|
||||
|
||||
let unlisten = js_sys::Function::from(unlisten);
|
||||
move || {
|
||||
unlisten.call0(&wasm_bindgen::JsValue::NULL).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
mod inner {
|
||||
use wasm_bindgen::{prelude::wasm_bindgen, JsValue};
|
||||
|
||||
#[wasm_bindgen(module = "/dist/event.js")]
|
||||
extern "C" {
|
||||
pub async fn emit(event: &str, payload: JsValue);
|
||||
pub async fn listen(event: &str, handler: &dyn Fn(JsValue)) -> JsValue;
|
||||
pub async fn once(event: &str, handler: &mut dyn FnMut(JsValue)) -> JsValue;
|
||||
}
|
||||
}
|
22
src/lib.rs
Normal file
22
src/lib.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
use wasm_bindgen::JsValue;
|
||||
|
||||
#[cfg(feature = "app")]
|
||||
pub mod app;
|
||||
#[cfg(feature = "clipboard")]
|
||||
pub mod clipboard;
|
||||
#[cfg(feature = "event")]
|
||||
pub mod event;
|
||||
#[cfg(feature = "mocks")]
|
||||
pub mod mocks;
|
||||
#[cfg(feature = "tauri")]
|
||||
pub mod tauri;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum Error {
|
||||
#[error(transparent)]
|
||||
Serde(#[from] serde_wasm_bindgen::Error),
|
||||
#[error("{0:?}")]
|
||||
Other(JsValue)
|
||||
}
|
||||
|
||||
pub(crate) type Result<T> = std::result::Result<T, Error>;
|
54
src/mocks.rs
Normal file
54
src/mocks.rs
Normal file
|
@ -0,0 +1,54 @@
|
|||
use js_sys::Array;
|
||||
use wasm_bindgen::JsValue;
|
||||
|
||||
/// Mocks the current window label
|
||||
/// In non-tauri context it is required to call this function///before* using the `@tauri-apps/api/window` module.
|
||||
///
|
||||
/// This function only mocks the *presence* of a window,
|
||||
/// window properties (e.g. width and height) can be mocked like regular IPC calls using the `mockIPC` function.
|
||||
pub fn mock_window(current: &str) {
|
||||
inner::mockWindows(
|
||||
current,
|
||||
JsValue::UNDEFINED,
|
||||
)
|
||||
}
|
||||
|
||||
/// Mocks many window labels.
|
||||
/// In non-tauri context it is required to call this function///before* using the `@tauri-apps/api/window` module.
|
||||
///
|
||||
/// This function only mocks the *presence* of windows,
|
||||
/// window properties (e.g. width and height) can be mocked like regular IPC calls using the `mockIPC` function.
|
||||
///
|
||||
/// @param current Label of window this JavaScript context is running in.
|
||||
/// @param additionalWindows Label of additional windows the app has.
|
||||
pub fn mock_windows(current: &str, additional_windows: &[&str]) {
|
||||
inner::mockWindows(
|
||||
current,
|
||||
Array::from_iter(additional_windows.iter().map(|str| JsValue::from_str(str))).into(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Intercepts all IPC requests with the given mock handler.
|
||||
///
|
||||
/// This function can be used when testing tauri frontend applications or when running the frontend in a Node.js context during static site generation.
|
||||
pub fn mock_ipc(handler: &dyn Fn(JsValue)) {
|
||||
inner::mockIPC(handler);
|
||||
}
|
||||
|
||||
/// Clears mocked functions/data injected by the other functions in this module.
|
||||
/// When using a test runner that doesn't provide a fresh window object for each test, calling this function will reset tauri specific properties.
|
||||
pub fn clear_mocks() {
|
||||
inner::clearMocks()
|
||||
}
|
||||
|
||||
mod inner {
|
||||
use wasm_bindgen::{prelude::wasm_bindgen, JsValue};
|
||||
|
||||
#[wasm_bindgen(module = "/dist/mocks.js")]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(variadic)]
|
||||
pub fn mockWindows(current: &str, rest: JsValue);
|
||||
pub fn mockIPC(handler: &dyn Fn(JsValue));
|
||||
pub fn clearMocks();
|
||||
}
|
||||
}
|
100
src/tauri.rs
Normal file
100
src/tauri.rs
Normal file
|
@ -0,0 +1,100 @@
|
|||
use serde::{de::DeserializeOwned, Serialize};
|
||||
use url::Url;
|
||||
|
||||
/// 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.
|
||||
///
|
||||
/// Additionally, `asset` must be added to [`tauri.allowlist.protocol`](https://tauri.app/v1/api/config/#allowlistconfig.protocol)
|
||||
/// in `tauri.conf.json` and its access scope must be defined on the `assetScope` array on the same `protocol` object.
|
||||
///
|
||||
/// @param filePath The file path.
|
||||
/// @param protocol The protocol to use. Defaults to `asset`. You only need to set this when using a custom protocol.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use tauri_api::path::{app_data_dir, join};
|
||||
/// use tauri_api::tauri::convert_file_src;
|
||||
///
|
||||
/// const app_data_dir_path = app_data_dir().await;
|
||||
/// const file_path = join(app_data_dir_path, "assets/video.mp4").await;
|
||||
/// const asset_url = convert_file_src(file_path);
|
||||
///
|
||||
/// let window = web_sys::window().expect("no global `window` exists");
|
||||
/// let document = window.document().expect("should have a document on window");
|
||||
///
|
||||
/// // Manufacture the element we're gonna append
|
||||
/// let video = document.get_element_by_id("my-video")?;
|
||||
/// let source = document.create_element("source")?;
|
||||
///
|
||||
/// source.set_attribute("type", "video/mp4")?;
|
||||
/// source.set_attribute("src", asset_url.as_str())?;
|
||||
///
|
||||
/// video.append_child(&val)?;
|
||||
/// ```
|
||||
///
|
||||
/// @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()
|
||||
}
|
||||
|
||||
/// Sends a message to the backend.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use tauri_api::tauri::invoke;
|
||||
///
|
||||
/// struct User<'a> {
|
||||
/// user: &'a str,
|
||||
/// password: &'a str
|
||||
/// }
|
||||
///
|
||||
/// invoke("login", &User { user: "tauri", password: "poiwe3h4r5ip3yrhtew9ty" }).await;
|
||||
/// ```
|
||||
///
|
||||
/// @param cmd The command name.
|
||||
/// @param args The optional arguments to pass to the command.
|
||||
/// @return A promise resolving or rejecting to the backend response.
|
||||
#[inline(always)]
|
||||
pub async fn invoke<A: Serialize, R: DeserializeOwned>(cmd: &str, args: &A) -> crate::Result<R> {
|
||||
let res = inner::invoke(cmd, serde_wasm_bindgen::to_value(args).unwrap()).await;
|
||||
|
||||
let raw = res.map_err(crate::Error::Other)?;
|
||||
serde_wasm_bindgen::from_value(raw).map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Transforms a callback function to a string identifier that can be passed to the backend.
|
||||
/// The backend uses the identifier to `eval()` the callback.
|
||||
///
|
||||
/// @return A unique identifier associated with the callback function.
|
||||
#[inline(always)]
|
||||
pub async fn transform_callback<T: DeserializeOwned>(callback: &dyn Fn(T), once: bool) -> f64 {
|
||||
inner::transformCallback(
|
||||
&|raw| callback(serde_wasm_bindgen::from_value(raw).unwrap()),
|
||||
once,
|
||||
)
|
||||
.await
|
||||
.as_f64()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
mod inner {
|
||||
use wasm_bindgen::{prelude::wasm_bindgen, JsValue};
|
||||
|
||||
#[wasm_bindgen(module = "/dist/tauri.js")]
|
||||
extern "C" {
|
||||
pub async fn convertFileSrc(filePath: &str, protocol: Option<&str>) -> JsValue;
|
||||
#[wasm_bindgen(catch)]
|
||||
pub async fn invoke(cmd: &str, args: JsValue) -> Result<JsValue, JsValue>;
|
||||
pub async fn transformCallback(callback: &dyn Fn(JsValue), once: bool) -> JsValue;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue