Create closure type; allow async event handlers in props; allow short hand event handlers (#2437)

* create closure type; allow async event handlers in props; allow shorthand event handlers

* test forwarding event handlers with the shorthand syntax

* fix clippy

* fix imports in spawn async doctest
This commit is contained in:
Evan Almloff authored and GitHub committed 2024-06-10 18:47:07 -07:00
1 parent 79e18c2d62
commit d795995e20
11 files changed
+294 -103

No files matched your search

+19 -15
View File
@@ -520,7 +520,7 @@ mod struct_info {
empty_type, empty_type_tuple, expr_to_single_string, make_punctuated_single,
modify_types_generics_hack, path_to_single_string, strip_raw_ident_prefix, type_tuple,
};
use super::{child_owned_type, looks_like_event_handler_type, looks_like_signal_type};
use super::{child_owned_type, looks_like_callback_type, looks_like_signal_type};
#[derive(Debug)]
pub struct StructInfo<'a> {
@@ -634,12 +634,12 @@ mod struct_info {
let event_handlers_fields: Vec<_> = self
.included_fields()
.filter(|f| looks_like_event_handler_type(f.ty))
.filter(|f| looks_like_callback_type(f.ty))
.collect();
let regular_fields: Vec<_> = self
.included_fields()
.filter(|f| !looks_like_signal_type(f.ty) && !looks_like_event_handler_type(f.ty))
.filter(|f| !looks_like_signal_type(f.ty) && !looks_like_callback_type(f.ty))
.map(|f| {
let name = f.name;
quote!(#name)
@@ -1593,7 +1593,7 @@ Finally, call `.build()` to create the instance of `{name}`.
}
/// A helper function for paring types with a single generic argument.
fn extract_base_type_without_single_generic(ty: &Type) -> Option<syn::Path> {
fn extract_base_type_without_generics(ty: &Type) -> Option<syn::Path> {
let Type::Path(ty) = ty else {
return None;
};
@@ -1670,11 +1670,11 @@ fn remove_option_wrapper(type_: Type) -> Type {
/// Check if a type should be owned by the child component after conversion
fn child_owned_type(ty: &Type) -> bool {
looks_like_signal_type(ty) || looks_like_event_handler_type(ty)
looks_like_signal_type(ty) || looks_like_callback_type(ty)
}
fn looks_like_signal_type(ty: &Type) -> bool {
match extract_base_type_without_single_generic(ty) {
match extract_base_type_without_generics(ty) {
Some(path_without_generics) => {
path_without_generics == parse_quote!(dioxus_core::prelude::ReadOnlySignal)
|| path_without_generics == parse_quote!(prelude::ReadOnlySignal)
@@ -1684,13 +1684,16 @@ fn looks_like_signal_type(ty: &Type) -> bool {
}
}
fn looks_like_event_handler_type(ty: &Type) -> bool {
fn looks_like_callback_type(ty: &Type) -> bool {
let type_without_option = remove_option_wrapper(ty.clone());
match extract_base_type_without_single_generic(&type_without_option) {
match extract_base_type_without_generics(&type_without_option) {
Some(path_without_generics) => {
path_without_generics == parse_quote!(dioxus_core::prelude::EventHandler)
|| path_without_generics == parse_quote!(prelude::EventHandler)
|| path_without_generics == parse_quote!(EventHandler)
|| path_without_generics == parse_quote!(dioxus_core::prelude::Callback)
|| path_without_generics == parse_quote!(prelude::Callback)
|| path_without_generics == parse_quote!(Callback)
}
None => false,
}
@@ -1709,20 +1712,21 @@ fn test_looks_like_type() {
ReadOnlySignal<Option<i32>, UnsyncStorage>
)));
assert!(looks_like_event_handler_type(&parse_quote!(
assert!(looks_like_callback_type(&parse_quote!(
Option<EventHandler>
)));
assert!(looks_like_event_handler_type(&parse_quote!(
assert!(looks_like_callback_type(&parse_quote!(
std::option::Option<EventHandler<i32>>
)));
assert!(looks_like_event_handler_type(&parse_quote!(
assert!(looks_like_callback_type(&parse_quote!(
Option<EventHandler<MouseEvent>>
)));
assert!(looks_like_event_handler_type(&parse_quote!(
EventHandler<i32>
)));
assert!(looks_like_event_handler_type(&parse_quote!(EventHandler)));
assert!(looks_like_callback_type(&parse_quote!(EventHandler<i32>)));
assert!(looks_like_callback_type(&parse_quote!(EventHandler)));
assert!(looks_like_callback_type(&parse_quote!(Callback<i32>)));
assert!(looks_like_callback_type(&parse_quote!(Callback<i32, u32>)));
}
#[test]