Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(core): support generics (especially Param) in #[command] (#1622)
* wip: param argument proof of concept for #[command] * use macros for automatic type inference in commands * refactor command for better error handling * remove redundant ToTokens impl for Wrapper and Handler * create `StateP` to allow state to use type inference during commands * wrap State instead of T * remove accidental edit of attribute * remove StateP because we recommend `_: Window<P>` for type inference, the following function types are now supported: * Pat::Wild (arg: "_") * Pat::Struct (arg: final path segment) * Pat::TupleStruct (arg: final path segment) * add wildcard, struct, and tuple struct commands to examples * better unsupported command argument message * feat(examples): move some commands to a separate module * add change file Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
- Loading branch information
1 parent
c78db1b
commit 1453d4b
Showing
10 changed files
with
363 additions
and
179 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
--- | ||
"tauri-macros": patch | ||
--- | ||
|
||
`#[command]` now generates a macro instead of a function to allow passing through `Params` and other generics. | ||
`generate_handler!` has been changed to consume the generated `#[command]` macro |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
// Copyright 2019-2021 Tauri Programme within The Commons Conservancy | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// SPDX-License-Identifier: MIT | ||
|
||
use syn::{ | ||
parse::{Parse, ParseBuffer}, | ||
Ident, Path, Token, | ||
}; | ||
|
||
/// The items parsed from [`generate_handle!`](crate::generate_handle). | ||
pub struct Handler { | ||
paths: Vec<Path>, | ||
commands: Vec<Ident>, | ||
wrappers: Vec<Path>, | ||
} | ||
|
||
impl Parse for Handler { | ||
fn parse(input: &ParseBuffer) -> syn::Result<Self> { | ||
let paths = input.parse_terminated::<Path, Token![,]>(Path::parse)?; | ||
|
||
// parse the command names and wrappers from the passed paths | ||
let (commands, wrappers) = paths | ||
.iter() | ||
.map(|path| { | ||
let mut wrapper = path.clone(); | ||
let last = super::path_to_command(&mut wrapper); | ||
|
||
// the name of the actual command function | ||
let command = last.ident.clone(); | ||
|
||
// set the path to the command function wrapper | ||
last.ident = super::format_command_wrapper(&command); | ||
|
||
(command, wrapper) | ||
}) | ||
.unzip(); | ||
|
||
Ok(Self { | ||
paths: paths.into_iter().collect(), // remove punctuation separators | ||
commands, | ||
wrappers, | ||
}) | ||
} | ||
} | ||
|
||
impl From<Handler> for proc_macro::TokenStream { | ||
fn from( | ||
Handler { | ||
paths, | ||
commands, | ||
wrappers, | ||
}: Handler, | ||
) -> Self { | ||
quote::quote!(move |invoke| { | ||
let cmd = invoke.message.command(); | ||
match cmd { | ||
#(stringify!(#commands) => #wrappers!(#paths, invoke),)* | ||
_ => { | ||
invoke.resolver.reject(format!("command {} not found", cmd)) | ||
}, | ||
} | ||
}) | ||
.into() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// Copyright 2019-2021 Tauri Programme within The Commons Conservancy | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// SPDX-License-Identifier: MIT | ||
|
||
use proc_macro2::Ident; | ||
use syn::{Path, PathSegment}; | ||
|
||
pub use self::{ | ||
handler::Handler, | ||
wrapper::{Wrapper, WrapperBody}, | ||
}; | ||
|
||
mod handler; | ||
mod wrapper; | ||
|
||
/// The autogenerated wrapper ident. | ||
fn format_command_wrapper(function: &Ident) -> Ident { | ||
quote::format_ident!("__cmd__{}", function) | ||
} | ||
|
||
/// This function will panic if the passed [`syn::Path`] does not have any segments. | ||
fn path_to_command(path: &mut Path) -> &mut PathSegment { | ||
path | ||
.segments | ||
.last_mut() | ||
.expect("parsed syn::Path has no segment") | ||
} |
Oops, something went wrong.