1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
//! [![](https://github.com/tauri-apps/tauri/raw/dev/.github/splash.png)](https://tauri.app)
//!
//! Create macros for `tauri::Context`, invoke handler and commands leveraging the `tauri-codegen` crate.
#![doc(
html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png",
html_favicon_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png"
)]
use crate::context::ContextItems;
use proc_macro::TokenStream;
use syn::parse_macro_input;
mod command;
mod menu;
mod mobile;
mod runtime;
#[macro_use]
mod context;
/// Mark a function as a command handler. It creates a wrapper function with the necessary glue code.
///
/// # Stability
/// The output of this macro is managed internally by Tauri,
/// and should not be accessed directly on normal applications.
/// It may have breaking changes in the future.
#[proc_macro_attribute]
pub fn command(attributes: TokenStream, item: TokenStream) -> TokenStream {
command::wrapper(attributes, item)
}
#[proc_macro_attribute]
pub fn mobile_entry_point(attributes: TokenStream, item: TokenStream) -> TokenStream {
mobile::entry_point(attributes, item)
}
/// Accepts a list of commands functions. Creates a handler that allows commands to be called from JS with invoke().
///
/// # Examples
/// ```rust,ignore
/// use tauri_macros::{command, generate_handler};
/// #[command]
/// fn command_one() {
/// println!("command one called");
/// }
/// #[command]
/// fn command_two() {
/// println!("command two called");
/// }
/// fn main() {
/// let _handler = generate_handler![command_one, command_two];
/// }
/// ```
/// # Stability
/// The output of this macro is managed internally by Tauri,
/// and should not be accessed directly on normal applications.
/// It may have breaking changes in the future.
#[proc_macro]
pub fn generate_handler(item: TokenStream) -> TokenStream {
parse_macro_input!(item as command::Handler).into()
}
/// Reads a Tauri config file and generates a `::tauri::Context` based on the content.
///
/// # Stability
/// The output of this macro is managed internally by Tauri,
/// and should not be accessed directly on normal applications.
/// It may have breaking changes in the future.
#[proc_macro]
pub fn generate_context(items: TokenStream) -> TokenStream {
// this macro is exported from the context module
let path = parse_macro_input!(items as ContextItems);
context::generate_context(path).into()
}
/// Adds the default type for the last parameter (assumed to be runtime) for a specific feature.
///
/// e.g. To default the runtime generic to type `crate::Wry` when the `wry` feature is enabled, the
/// syntax would look like `#[default_runtime(crate::Wry, wry)`. This is **always** set for the last
/// generic, so make sure the last generic is the runtime when using this macro.
#[doc(hidden)]
#[proc_macro_attribute]
pub fn default_runtime(attributes: TokenStream, input: TokenStream) -> TokenStream {
let attributes = parse_macro_input!(attributes as runtime::Attributes);
let input = parse_macro_input!(input as runtime::Input);
runtime::default_runtime(attributes, input).into()
}
/// Accepts a closure-like syntax to call arbitrary code on a menu item
/// after matching against `kind` and retrieving it from `resources_table` using `rid`.
///
/// You can optionally pass a 5th parameter to select which item kinds
/// to match against, by providing a `|` separated list of item kinds
/// ```ignore
/// do_menu_item!(resources_table, rid, kind, |i| i.set_text(text), Check | Submenu);
/// ```
/// You could also provide a negated list
/// ```ignore
/// do_menu_item!(resources_table, rid, kind, |i| i.set_text(text), !Check);
/// do_menu_item!(resources_table, rid, kind, |i| i.set_text(text), !Check | !Submenu);
/// ```
/// but you can't have mixed negations and positive kinds.
/// ```ignore
/// do_menu_item!(resources_table, rid, kind, |i| i.set_text(text), !Check | Submeun);
/// ```
///
/// #### Example
///
/// ```ignore
/// let rid = 23;
/// let kind = ItemKind::Check;
/// let resources_table = app.resources_table();
/// do_menu_item!(resources_table, rid, kind, |i| i.set_text(text))
/// ```
/// which will expand into:
/// ```ignore
/// let rid = 23;
/// let kind = ItemKind::Check;
/// let resources_table = app.resources_table();
/// match kind {
/// ItemKind::Submenu => {
/// let i = resources_table.get::<Submenu<R>>(rid)?;
/// i.set_text(text)
/// }
/// ItemKind::MenuItem => {
/// let i = resources_table.get::<MenuItem<R>>(rid)?;
/// i.set_text(text)
/// }
/// ItemKind::Predefined => {
/// let i = resources_table.get::<PredefinedMenuItem<R>>(rid)?;
/// i.set_text(text)
/// }
/// ItemKind::Check => {
/// let i = resources_table.get::<CheckMenuItem<R>>(rid)?;
/// i.set_text(text)
/// }
/// ItemKind::Icon => {
/// let i = resources_table.get::<IconMenuItem<R>>(rid)?;
/// i.set_text(text)
/// }
/// _ => unreachable!(),
/// }
/// ```
#[proc_macro]
pub fn do_menu_item(input: TokenStream) -> TokenStream {
let tokens = parse_macro_input!(input as menu::DoMenuItemInput);
menu::do_menu_item(tokens).into()
}