diff --git a/packages/yew-macro/tests/html_macro/component-fail.stderr b/packages/yew-macro/tests/html_macro/component-fail.stderr index 8f34088e4ee..08ea30e6772 100644 --- a/packages/yew-macro/tests/html_macro/component-fail.stderr +++ b/packages/yew-macro/tests/html_macro/component-fail.stderr @@ -488,14 +488,14 @@ error[E0277]: the trait bound `{integer}: IntoPropValue` is not satisfie | required by a bound introduced by this call | = help: the following other types implement trait `IntoPropValue`: - &f32 - &f64 - &i128 - &i16 - &i32 - &i64 - &i8 - &isize + `&f32` implements `IntoPropValue>` + `&f32` implements `IntoPropValue` + `&f64` implements `IntoPropValue>` + `&f64` implements `IntoPropValue` + `&i128` implements `IntoPropValue>` + `&i128` implements `IntoPropValue` + `&i16` implements `IntoPropValue>` + `&i16` implements `IntoPropValue` and $N others note: required by a bound in `ChildPropertiesBuilder::string` --> tests/html_macro/component-fail.rs:4:17 @@ -516,14 +516,14 @@ error[E0277]: the trait bound `{integer}: IntoPropValue` is not satisfie | required by a bound introduced by this call | = help: the following other types implement trait `IntoPropValue`: - &f32 - &f64 - &i128 - &i16 - &i32 - &i64 - &i8 - &isize + `&f32` implements `IntoPropValue>` + `&f32` implements `IntoPropValue` + `&f64` implements `IntoPropValue>` + `&f64` implements `IntoPropValue` + `&i128` implements `IntoPropValue>` + `&i128` implements `IntoPropValue` + `&i16` implements `IntoPropValue>` + `&i16` implements `IntoPropValue` and $N others note: required by a bound in `ChildPropertiesBuilder::string` --> tests/html_macro/component-fail.rs:4:17 @@ -561,8 +561,10 @@ error[E0277]: the trait bound `u32: IntoPropValue` is not satisfied | required by a bound introduced by this call | = help: the following other types implement trait `IntoPropValue`: - &u32 - u32 + `&u32` implements `IntoPropValue>` + `&u32` implements `IntoPropValue` + `u32` implements `IntoPropValue>` + `u32` implements `IntoPropValue` note: required by a bound in `ChildPropertiesBuilder::int` --> tests/html_macro/component-fail.rs:4:17 | diff --git a/packages/yew-macro/tests/html_macro/element-fail.stderr b/packages/yew-macro/tests/html_macro/element-fail.stderr index cd2a87bb422..fc72592b38a 100644 --- a/packages/yew-macro/tests/html_macro/element-fail.stderr +++ b/packages/yew-macro/tests/html_macro/element-fail.stderr @@ -465,14 +465,14 @@ error[E0277]: the trait bound `NotToString: IntoPropValue>` is not implemented for `NotToString` | = help: the following other types implement trait `IntoPropValue`: + `&&String` implements `IntoPropValue>` `&&String` implements `IntoPropValue` + `&&str` implements `IntoPropValue>` `&&str` implements `IntoPropValue` `&'static [(K, V)]` implements `IntoPropValue>` `&'static [T]` implements `IntoPropValue>` `&'static str` implements `IntoPropValue` `&'static str` implements `IntoPropValue>` - `&'static str` implements `IntoPropValue>` - `&'static str` implements `IntoPropValue` and $N others error[E0277]: the trait bound `Option: IntoPropValue>` is not satisfied @@ -485,14 +485,15 @@ error[E0277]: the trait bound `Option: IntoPropValue`: + `Option<&String>` implements `IntoPropValue>` + `Option<&implicit_clone::unsync::string::IString>` implements `IntoPropValue>` `Option<&str>` implements `IntoPropValue>` + `Option<&str>` implements `IntoPropValue>` `Option<&str>` implements `IntoPropValue>` - `Option>` implements `IntoPropValue>` - `Option` implements `IntoPropValue>>` - `Option>` implements `IntoPropValue>` - `Option` implements `IntoPropValue>` - `Option` implements `IntoPropValue` - `Option>` implements `IntoPropValue>>` + `Option>` implements `IntoPropValue>` + `Option>` implements `IntoPropValue>` + `Option>` implements `IntoPropValue>` + and $N others error[E0277]: the trait bound `Option<{integer}>: IntoPropValue>` is not satisfied --> tests/html_macro/element-fail.rs:48:22 @@ -504,14 +505,15 @@ error[E0277]: the trait bound `Option<{integer}>: IntoPropValue`: + `Option<&String>` implements `IntoPropValue>` + `Option<&implicit_clone::unsync::string::IString>` implements `IntoPropValue>` `Option<&str>` implements `IntoPropValue>` + `Option<&str>` implements `IntoPropValue>` `Option<&str>` implements `IntoPropValue>` - `Option>` implements `IntoPropValue>` - `Option` implements `IntoPropValue>>` - `Option>` implements `IntoPropValue>` - `Option` implements `IntoPropValue>` - `Option` implements `IntoPropValue` - `Option>` implements `IntoPropValue>>` + `Option>` implements `IntoPropValue>` + `Option>` implements `IntoPropValue>` + `Option>` implements `IntoPropValue>` + and $N others error[E0277]: the trait bound `{integer}: IntoEventCallback` is not satisfied --> tests/html_macro/element-fail.rs:51:28 @@ -621,14 +623,15 @@ error[E0277]: the trait bound `Option: IntoPropValue | required by a bound introduced by this call | = help: the following other types implement trait `IntoPropValue`: + `Option<&String>` implements `IntoPropValue>` + `Option<&implicit_clone::unsync::string::IString>` implements `IntoPropValue>` `Option<&str>` implements `IntoPropValue>` + `Option<&str>` implements `IntoPropValue>` `Option<&str>` implements `IntoPropValue>` - `Option>` implements `IntoPropValue>` - `Option` implements `IntoPropValue>>` - `Option>` implements `IntoPropValue>` - `Option` implements `IntoPropValue>` - `Option` implements `IntoPropValue` - `Option>` implements `IntoPropValue>>` + `Option>` implements `IntoPropValue>` + `Option>` implements `IntoPropValue>` + `Option>` implements `IntoPropValue>` + and $N others error[E0277]: the trait bound `yew::Callback: IntoEventCallback` is not satisfied --> tests/html_macro/element-fail.rs:58:29 @@ -665,14 +668,14 @@ error[E0277]: the trait bound `NotToString: IntoPropValue>` is not implemented for `NotToString` | = help: the following other types implement trait `IntoPropValue`: + `&&String` implements `IntoPropValue>` `&&String` implements `IntoPropValue` + `&&str` implements `IntoPropValue>` `&&str` implements `IntoPropValue` `&'static [(K, V)]` implements `IntoPropValue>` `&'static [T]` implements `IntoPropValue>` `&'static str` implements `IntoPropValue` `&'static str` implements `IntoPropValue>` - `&'static str` implements `IntoPropValue>` - `&'static str` implements `IntoPropValue` and $N others error[E0277]: the trait bound `(): IntoPropValue` is not satisfied diff --git a/packages/yew/src/html/conversion/into_prop_value.rs b/packages/yew/src/html/conversion/into_prop_value.rs index 05f8a99bcb4..889cd975833 100644 --- a/packages/yew/src/html/conversion/into_prop_value.rs +++ b/packages/yew/src/html/conversion/into_prop_value.rs @@ -298,6 +298,24 @@ macro_rules! impl_into_prop_value_via_display { self.clone().into_prop_value() } } + impl IntoPropValue> for $from_ty { + #[inline(always)] + fn into_prop_value(self) -> Option { + Some(IntoPropValue::::into_prop_value(self)) + } + } + impl IntoPropValue> for &$from_ty { + #[inline(always)] + fn into_prop_value(self) -> Option { + Some(IntoPropValue::::into_prop_value(self)) + } + } + impl IntoPropValue> for Option<$from_ty> { + #[inline(always)] + fn into_prop_value(self) -> Option { + self.map(IntoPropValue::::into_prop_value) + } + } }; } @@ -310,6 +328,18 @@ macro_rules! impl_into_prop_value_via_attr_value { VText::new(self).into() } } + impl IntoPropValue> for $from_ty { + #[inline(always)] + fn into_prop_value(self) -> Option { + Some(VText::new(self).into()) + } + } + impl IntoPropValue> for Option<$from_ty> { + #[inline(always)] + fn into_prop_value(self) -> Option { + self.map(|v| VText::new(v).into()) + } + } }; } @@ -368,6 +398,28 @@ mod test { let _: VNode = Some(true).into_prop_value(); } + #[test] + fn test_into_option_vnode() { + // T -> Option + let _: Option = "hello".into_prop_value(); + let _: Option = String::from("hello").into_prop_value(); + let _: Option = AttrValue::Static("hello").into_prop_value(); + let _: Option = 42u32.into_prop_value(); + let _: Option = true.into_prop_value(); + // &T -> Option + let _: Option = (&42u32).into_prop_value(); + let _: Option = (&true).into_prop_value(); + let s = String::from("hello"); + let _: Option = (&s).into_prop_value(); + // Option -> Option + let _: Option = Some("hello").into_prop_value(); + let _: Option = Option::<&str>::None.into_prop_value(); + let _: Option = Some(String::from("hello")).into_prop_value(); + let _: Option = Option::::None.into_prop_value(); + let _: Option = Some(42u32).into_prop_value(); + let _: Option = Some(true).into_prop_value(); + } + #[test] fn test_ref_to_vnode() { let _: VNode = (&42i32).into_prop_value(); @@ -646,4 +698,30 @@ mod test { let _ = html! { }; let _ = html! { }; } + + #[test] + fn test_option_html_prop_compiles() { + use crate::prelude::*; + + #[derive(PartialEq, Properties)] + pub struct Props { + pub title: Option, + } + + #[component] + fn Foo(props: &Props) -> Html { + match &props.title { + Some(title) => html! {

{ title.clone() }

}, + None => html! {}, + } + } + + let _ = html! { }; + + let _ = html! { }; + + let _ = html! { }; + + let _ = html! { ::None} /> }; + } }