Skip to content

feat(core): improved command matching with macros, fixes #1157 - #1301

Merged
nklayman merged 27 commits into
devfrom
feat/better-command-matching
Feb 28, 2021
Merged

feat(core): improved command matching with macros, fixes #1157#1301
nklayman merged 27 commits into
devfrom
feat/better-command-matching

Conversation

@nklayman

@nklayman nklayman commented Feb 26, 2021

Copy link
Copy Markdown
Member

What kind of change does this PR introduce? (check at least one)

  • Bugfix
  • Feature
  • New Binding Issue #___
  • Code style update
  • Refactor
  • Build-related changes
  • Other, please describe:

Does this PR introduce a breaking change? (check one)

  • Yes. Issue #___
  • No
  • Kinda

The PR fulfills these requirements:

  • When resolving a specific issue, it's referenced in the PR's title (e.g. fix: #xxx[,#xxx], where "xxx" is the issue number)
  • A change file is added if any packages will require a version bump due to this PR per the instructions in the readme.

If adding a new feature, the PR's description includes:

  • A convincing reason for adding this feature (to avoid wasting your time, it's best to open a suggestion issue first and wait for approval before working on it)

Other information:

This PR adds two macros, #[command] and generate_handler![]. Combined, these allow command handling to look like this:

// Definition in main.rs

#[command]
fn reply_string(s: String) -> String {
  s
}
// Or, if the function needs the WebviewManager
#[command(with_manager)]
fn reply_string(manager: tauri::WebviewManager, s: String) -> String {
  println!("{}", manager.current_window_label());
  s
}

fn main() {
  tauri::AppBuilder::<Context>::new()
    .invoke_handler(generate_handler![reply_string])
    .build()
    .unwrap()
    .run();
}
// Calling from js
window.__TAURI__
  .invoke({
    cmd: 'reply_string',
    s: 'Hi'
  })
  .then((res) => console.log('Response:', res))

#[command] adds a second function, NAME_wrapper to function with name NAME. This wrapper function accepts the WebviewManager and serde_json::Value as args, and returns a tauri::InvokeResponse. The serde_json::Value should match the names and types of the original function args, ie the JSON for fn original(name: String) would be {"name": "some string"}. The wrapper function casts the value to a typed struct that contains all the function args, and passes them to the original function. It also passes the WebviewManager as the first arg if it is a with_webview command. It then converts the response from the original function to a tauri::InvokeResponse, and then returns it.

The generate_handler![] macro takes an array of paths to #[command] functions and returns a closure compatible with invoke_handler. This closure parses the arg string into a tauri::DispatchInstructions, a simple struct with two params: cmd, a string and args, a serde_json::Value. The cmd param is used in a generated match statement that matches it to one of the functions passed to this macro. It then calls that function's wrapper function with the WebviewManager and args, the JSON value that should hold all of that function's arguments. It returns the output from that function back to the webview.

TODO:

  • Clean up macro and use less .unwrap()
  • Have commands return a Result for better error handling
  • Improve error message from arg parse failure
  • Add support for functions that take the webview as an arg
  • Support for inferring webview arg type We decided to not include this
  • Support async functions
  • Update JS API to have cleaner syntax
  • Update init template to use macros
  • Update examples to use macros
  • (after merge) Type check the webview arg for with_webview commands
  • (after merge) Add support for state/context

Comment thread tauri/src/app.rs
Comment thread tauri-macros/src/command.rs Outdated

@chippers chippers left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can use the root crate path to prevent any collisions with any in-scope items that clash (more likely for Result, but also possible for the crate names)

Comment thread tauri-macros/src/command.rs Outdated
Comment thread tauri-macros/src/command.rs Outdated
Comment thread tauri-macros/src/command.rs Outdated
Comment thread tauri-macros/src/command.rs Outdated
Comment thread tauri-macros/src/command.rs Outdated
Comment thread tauri-macros/src/command.rs Outdated
@nklayman
nklayman marked this pull request as ready for review February 28, 2021 05:05
@nklayman
nklayman requested a review from a team as a code owner February 28, 2021 05:05
@nklayman
nklayman requested a review from a team February 28, 2021 05:05
@nklayman
nklayman requested a review from a team February 28, 2021 05:05
@nklayman
nklayman merged commit 1f2e7a3 into dev Feb 28, 2021
@nklayman
nklayman deleted the feat/better-command-matching branch February 28, 2021 18:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants