Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #2553 - automatically convert closure to callback for component properties #2554

Merged
merged 4 commits into from Mar 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/yew-macro/tests/html_macro/component-fail.stderr
Expand Up @@ -346,7 +346,7 @@ error[E0277]: the trait bound `{integer}: IntoPropValue<String>` is not satisfie
<&'static str as IntoPropValue<Classes>>
<&'static str as IntoPropValue<Option<AttrValue>>>
<&'static str as IntoPropValue<Option<String>>>
and 15 others
and 18 others

error[E0277]: the trait bound `{integer}: IntoPropValue<String>` is not satisfied
--> tests/html_macro/component-fail.rs:79:34
Expand All @@ -359,7 +359,7 @@ error[E0277]: the trait bound `{integer}: IntoPropValue<String>` is not satisfie
<&'static str as IntoPropValue<Classes>>
<&'static str as IntoPropValue<Option<AttrValue>>>
<&'static str as IntoPropValue<Option<String>>>
and 15 others
and 18 others

error[E0308]: mismatched types
--> tests/html_macro/component-fail.rs:80:31
Expand Down
3 changes: 3 additions & 0 deletions packages/yew-macro/tests/html_macro/element-fail.stderr
Expand Up @@ -303,6 +303,7 @@ error[E0277]: the trait bound `Option<NotToString>: IntoPropValue<Option<AttrVal
= help: the following implementations were found:
<Option<&'static str> as IntoPropValue<Option<AttrValue>>>
<Option<&'static str> as IntoPropValue<Option<String>>>
<Option<F> as IntoPropValue<Option<yew::Callback<I, O>>>>
<Option<String> as IntoPropValue<Option<AttrValue>>>
<Option<std::rc::Rc<str>> as IntoPropValue<Option<AttrValue>>>
note: required by `into_prop_value`
Expand All @@ -320,6 +321,7 @@ error[E0277]: the trait bound `Option<{integer}>: IntoPropValue<Option<AttrValue
= help: the following implementations were found:
<Option<&'static str> as IntoPropValue<Option<AttrValue>>>
<Option<&'static str> as IntoPropValue<Option<String>>>
<Option<F> as IntoPropValue<Option<yew::Callback<I, O>>>>
<Option<String> as IntoPropValue<Option<AttrValue>>>
<Option<std::rc::Rc<str>> as IntoPropValue<Option<AttrValue>>>
note: required by `into_prop_value`
Expand Down Expand Up @@ -416,6 +418,7 @@ error[E0277]: the trait bound `Option<yew::NodeRef>: IntoPropValue<yew::NodeRef>
= help: the following implementations were found:
<Option<&'static str> as IntoPropValue<Option<AttrValue>>>
<Option<&'static str> as IntoPropValue<Option<String>>>
<Option<F> as IntoPropValue<Option<yew::Callback<I, O>>>>
<Option<String> as IntoPropValue<Option<AttrValue>>>
<Option<std::rc::Rc<str>> as IntoPropValue<Option<AttrValue>>>
note: required by `into_prop_value`
Expand Down
38 changes: 38 additions & 0 deletions packages/yew/src/html/conversion.rs
@@ -1,3 +1,4 @@
use super::super::callback::Callback;
use super::{Component, NodeRef, Scope};
use crate::virtual_dom::AttrValue;
use std::rc::Rc;
Expand Down Expand Up @@ -64,6 +65,33 @@ where
}
}

impl<I, O, F> IntoPropValue<Callback<I, O>> for F
where
F: 'static + Fn(I) -> O,
{
fn into_prop_value(self) -> Callback<I, O> {
Callback::from(self)
}
}

impl<I, O, F> IntoPropValue<Option<Callback<I, O>>> for F
where
F: 'static + Fn(I) -> O,
{
fn into_prop_value(self) -> Option<Callback<I, O>> {
Some(Callback::from(self))
}
}

impl<I, O, F> IntoPropValue<Option<Callback<I, O>>> for Option<F>
where
F: 'static + Fn(I) -> O,
{
fn into_prop_value(self) -> Option<Callback<I, O>> {
self.map(|f| Callback::from(f))
}
}

macro_rules! impl_into_prop {
(|$value:ident: $from_ty:ty| -> $to_ty:ty { $conversion:expr }) => {
// implement V -> T
Expand Down Expand Up @@ -111,4 +139,14 @@ mod test {
let _: Option<AttrValue> = "foo".into_prop_value();
let _: Option<AttrValue> = Rc::<str>::from("foo").into_prop_value();
}

#[test]
fn test_callback() {
let _: Callback<String> = (|_: String| ()).into_prop_value();
let _: Option<Callback<String>> = (|_: String| ()).into_prop_value();
let _: Option<Callback<String>> = Some(|_: String| ()).into_prop_value();
let _: Callback<String, String> = (|s: String| s).into_prop_value();
let _: Option<Callback<String, String>> = (|s: String| s).into_prop_value();
let _: Option<Callback<String, String>> = Some(|s: String| s).into_prop_value();
}
}