From f30be11a96c8e88528584f7d42ea71f3caa50618 Mon Sep 17 00:00:00 2001 From: Jens Reimann Date: Wed, 2 Jun 2021 11:38:19 +0200 Subject: [PATCH] Bring back &str assignment to optional properties This drops the "optional" conversion concept in favor of directly converting to `Option`. fixes #1888 --- .../tests/html_macro/block-fail.stderr | 4 +- .../tests/html_macro/component-fail.stderr | 12 ++-- .../tests/html_macro/element-fail.stderr | 70 +++++++++---------- .../tests/html_macro/iterable-fail.stderr | 4 +- packages/yew/src/html/classes.rs | 6 +- packages/yew/src/html/conversion.rs | 30 ++++---- packages/yew/src/html/listener/macros.rs | 6 +- packages/yew/src/virtual_dom/mod.rs | 6 +- packages/yew/src/virtual_dom/vtag.rs | 10 +-- 9 files changed, 72 insertions(+), 76 deletions(-) diff --git a/packages/yew-macro/tests/html_macro/block-fail.stderr b/packages/yew-macro/tests/html_macro/block-fail.stderr index 26fb5992164..16599d28cb6 100644 --- a/packages/yew-macro/tests/html_macro/block-fail.stderr +++ b/packages/yew-macro/tests/html_macro/block-fail.stderr @@ -34,9 +34,9 @@ error[E0277]: `()` doesn't implement `std::fmt::Display` 15 | <>{ for (0..3).map(|_| not_tree()) } | ^^^^^^ `()` cannot be formatted with the default formatter | - ::: $WORKSPACE/packages/yew/src/utils.rs + ::: $WORKSPACE/packages/yew/src/utils.rs:51:8 | - | T: Into, +51 | T: Into, | ------- required by this bound in `into_node_iter` | = help: the trait `std::fmt::Display` is not implemented for `()` diff --git a/packages/yew-macro/tests/html_macro/component-fail.stderr b/packages/yew-macro/tests/html_macro/component-fail.stderr index 23c2fd1b795..20915753fed 100644 --- a/packages/yew-macro/tests/html_macro/component-fail.stderr +++ b/packages/yew-macro/tests/html_macro/component-fail.stderr @@ -213,10 +213,10 @@ error[E0277]: the trait bound `{integer}: IntoPropValue` is not satisfie | = help: the following implementations were found: <&'static str as IntoPropValue>> + <&'static str as IntoPropValue>>> + <&'static str as IntoPropValue>> <&'static str as IntoPropValue> - <&T as IntoPropValue>> - <&T as IntoPropValue> - and 4 others + and 11 others error[E0277]: the trait bound `{integer}: IntoPropValue` is not satisfied --> $DIR/component-fail.rs:79:26 @@ -226,10 +226,10 @@ error[E0277]: the trait bound `{integer}: IntoPropValue` is not satisfie | = help: the following implementations were found: <&'static str as IntoPropValue>> + <&'static str as IntoPropValue>>> + <&'static str as IntoPropValue>> <&'static str as IntoPropValue> - <&T as IntoPropValue>> - <&T as IntoPropValue> - and 4 others + and 11 others error[E0308]: mismatched types --> $DIR/component-fail.rs:80:30 diff --git a/packages/yew-macro/tests/html_macro/element-fail.stderr b/packages/yew-macro/tests/html_macro/element-fail.stderr index eb4857b2a2e..a232fef9da6 100644 --- a/packages/yew-macro/tests/html_macro/element-fail.stderr +++ b/packages/yew-macro/tests/html_macro/element-fail.stderr @@ -185,16 +185,12 @@ error[E0277]: the trait bound `(): IntoPropValue>>` is | 43 | html! { }; | ^^ the trait `IntoPropValue>>` is not implemented for `()` - | - = note: required because of the requirements on the impl of `IntoOptPropValue>` for `()` error[E0277]: the trait bound `(): IntoPropValue>>` is not satisfied --> $DIR/element-fail.rs:44:26 | 44 | html! { }; | ^^ the trait `IntoPropValue>>` is not implemented for `()` - | - = note: required because of the requirements on the impl of `IntoOptPropValue>` for `()` error[E0277]: the trait bound `(): IntoPropValue>>` is not satisfied --> $DIR/element-fail.rs:45:21 @@ -202,12 +198,10 @@ error[E0277]: the trait bound `(): IntoPropValue>>` is 45 | html! { }; | ^^ the trait `IntoPropValue>>` is not implemented for `()` | - ::: $WORKSPACE/packages/yew/src/virtual_dom/mod.rs + ::: $WORKSPACE/packages/yew/src/virtual_dom/mod.rs:61:47 | - | pub fn new(key: &'static str, value: impl IntoOptPropValue) -> Self { - | --------------------------- required by this bound in `PositionalAttr::new` - | - = note: required because of the requirements on the impl of `IntoOptPropValue>` for `()` +61 | pub fn new(key: &'static str, value: impl IntoPropValue>) -> Self { + | -------------------------------- required by this bound in `PositionalAttr::new` error[E0277]: the trait bound `NotToString: IntoPropValue>>` is not satisfied --> $DIR/element-fail.rs:46:27 @@ -215,12 +209,10 @@ error[E0277]: the trait bound `NotToString: IntoPropValue }; | ^^^^^^^^^^^ the trait `IntoPropValue>>` is not implemented for `NotToString` | - ::: $WORKSPACE/packages/yew/src/virtual_dom/mod.rs - | - | pub fn new(key: &'static str, value: impl IntoOptPropValue) -> Self { - | --------------------------- required by this bound in `PositionalAttr::new` + ::: $WORKSPACE/packages/yew/src/virtual_dom/mod.rs:61:47 | - = note: required because of the requirements on the impl of `IntoOptPropValue>` for `NotToString` +61 | pub fn new(key: &'static str, value: impl IntoPropValue>) -> Self { + | -------------------------------- required by this bound in `PositionalAttr::new` error[E0277]: the trait bound `Option: IntoPropValue>>` is not satisfied --> $DIR/element-fail.rs:47:22 @@ -228,12 +220,15 @@ error[E0277]: the trait bound `Option: IntoPropValue }; | ^^^^^^^^^^^^^^^^^ the trait `IntoPropValue>>` is not implemented for `Option` | - ::: $WORKSPACE/packages/yew/src/virtual_dom/mod.rs + ::: $WORKSPACE/packages/yew/src/virtual_dom/mod.rs:61:47 | - | pub fn new(key: &'static str, value: impl IntoOptPropValue) -> Self { - | --------------------------- required by this bound in `PositionalAttr::new` +61 | pub fn new(key: &'static str, value: impl IntoPropValue>) -> Self { + | -------------------------------- required by this bound in `PositionalAttr::new` | - = note: required because of the requirements on the impl of `IntoOptPropValue>` for `Option` + = help: the following implementations were found: + as IntoPropValue>>> + as IntoPropValue>> + as IntoPropValue>>> error[E0277]: the trait bound `Option<{integer}>: IntoPropValue>>` is not satisfied --> $DIR/element-fail.rs:48:21 @@ -241,12 +236,15 @@ error[E0277]: the trait bound `Option<{integer}>: IntoPropValue }; | ^^^^^^^ the trait `IntoPropValue>>` is not implemented for `Option<{integer}>` | - ::: $WORKSPACE/packages/yew/src/virtual_dom/mod.rs + ::: $WORKSPACE/packages/yew/src/virtual_dom/mod.rs:61:47 | - | pub fn new(key: &'static str, value: impl IntoOptPropValue) -> Self { - | --------------------------- required by this bound in `PositionalAttr::new` +61 | pub fn new(key: &'static str, value: impl IntoPropValue>) -> Self { + | -------------------------------- required by this bound in `PositionalAttr::new` | - = note: required because of the requirements on the impl of `IntoOptPropValue>` for `Option<{integer}>` + = help: the following implementations were found: + as IntoPropValue>>> + as IntoPropValue>> + as IntoPropValue>>> error[E0277]: the trait bound `{integer}: IntoPropValue>>` is not satisfied --> $DIR/element-fail.rs:51:28 @@ -254,9 +252,9 @@ error[E0277]: the trait bound `{integer}: IntoPropValue }; | ^ the trait `IntoPropValue>>` is not implemented for `{integer}` | - ::: $WORKSPACE/packages/yew/src/html/listener/events.rs + ::: $WORKSPACE/packages/yew/src/html/listener/events.rs:2:1 | - | / impl_action! { +2 | / impl_action! { 3 | | onabort(name: "abort", event: Event) -> web_sys::Event => |_, event| { event } 4 | | onauxclick(name: "auxclick", event: MouseEvent) -> web_sys::MouseEvent => |_, event| { event } 5 | | onblur(name: "blur", event: FocusEvent) -> web_sys::FocusEvent => |_, event| { event } @@ -267,11 +265,10 @@ error[E0277]: the trait bound `{integer}: IntoPropValue>> + <&'static str as IntoPropValue>>> + <&'static str as IntoPropValue>> <&'static str as IntoPropValue> - <&T as IntoPropValue>> - <&T as IntoPropValue> - and 4 others - = note: required because of the requirements on the impl of `IntoOptPropValue>` for `{integer}` + and 11 others error[E0277]: the trait bound `yew::Callback: IntoPropValue>>` is not satisfied --> $DIR/element-fail.rs:52:28 @@ -279,9 +276,9 @@ error[E0277]: the trait bound `yew::Callback: IntoPropValue }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `IntoPropValue>>` is not implemented for `yew::Callback` | - ::: $WORKSPACE/packages/yew/src/html/listener/events.rs + ::: $WORKSPACE/packages/yew/src/html/listener/events.rs:2:1 | - | / impl_action! { +2 | / impl_action! { 3 | | onabort(name: "abort", event: Event) -> web_sys::Event => |_, event| { event } 4 | | onauxclick(name: "auxclick", event: MouseEvent) -> web_sys::MouseEvent => |_, event| { event } 5 | | onblur(name: "blur", event: FocusEvent) -> web_sys::FocusEvent => |_, event| { event } @@ -289,8 +286,6 @@ error[E0277]: the trait bound `yew::Callback: IntoPropValue web_sys::TransitionEvent => |_, event| { event } 100 | | } | |_- required by this bound in `yew::html::onclick::Wrapper::__macro_new` - | - = note: required because of the requirements on the impl of `IntoOptPropValue>` for `yew::Callback` error[E0277]: the trait bound `Option<{integer}>: IntoPropValue>>` is not satisfied --> $DIR/element-fail.rs:53:28 @@ -298,9 +293,9 @@ error[E0277]: the trait bound `Option<{integer}>: IntoPropValue }; | ^^^^^^^ the trait `IntoPropValue>>` is not implemented for `Option<{integer}>` | - ::: $WORKSPACE/packages/yew/src/html/listener/events.rs + ::: $WORKSPACE/packages/yew/src/html/listener/events.rs:2:1 | - | / impl_action! { +2 | / impl_action! { 3 | | onabort(name: "abort", event: Event) -> web_sys::Event => |_, event| { event } 4 | | onauxclick(name: "auxclick", event: MouseEvent) -> web_sys::MouseEvent => |_, event| { event } 5 | | onblur(name: "blur", event: FocusEvent) -> web_sys::FocusEvent => |_, event| { event } @@ -309,7 +304,10 @@ error[E0277]: the trait bound `Option<{integer}>: IntoPropValue>` for `Option<{integer}>` + = help: the following implementations were found: + as IntoPropValue>>> + as IntoPropValue>> + as IntoPropValue>>> error[E0308]: mismatched types --> $DIR/element-fail.rs:56:24 @@ -339,4 +337,4 @@ error[E0277]: the trait bound `Cow<'static, str>: From<{integer}>` is not satisf as From<&'a OsStr>> and 11 others = note: required because of the requirements on the impl of `Into>` for `{integer}` - = note: required by `into` + = note: required by `into` \ No newline at end of file diff --git a/packages/yew-macro/tests/html_macro/iterable-fail.stderr b/packages/yew-macro/tests/html_macro/iterable-fail.stderr index 02b832ae5a7..84502b7917f 100644 --- a/packages/yew-macro/tests/html_macro/iterable-fail.stderr +++ b/packages/yew-macro/tests/html_macro/iterable-fail.stderr @@ -70,9 +70,9 @@ error[E0277]: `()` is not an iterator 18 | { for () } | ^^ `()` is not an iterator | - ::: $WORKSPACE/packages/yew/src/utils.rs + ::: $WORKSPACE/packages/yew/src/utils.rs:50:9 | - | IT: IntoIterator, +50 | IT: IntoIterator, | ---------------------- required by this bound in `into_node_iter` | = help: the trait `Iterator` is not implemented for `()` diff --git a/packages/yew/src/html/classes.rs b/packages/yew/src/html/classes.rs index 5af9aee39e0..2f8fce80434 100644 --- a/packages/yew/src/html/classes.rs +++ b/packages/yew/src/html/classes.rs @@ -1,4 +1,4 @@ -use super::{IntoOptPropValue, IntoPropValue}; +use super::IntoPropValue; use crate::virtual_dom::AttrValue; use indexmap::IndexSet; use std::{ @@ -74,8 +74,8 @@ impl IntoPropValue for Classes { } } -impl IntoOptPropValue for Classes { - fn into_opt_prop_value(self) -> Option { +impl IntoPropValue> for Classes { + fn into_prop_value(self) -> Option { if self.is_empty() { None } else { diff --git a/packages/yew/src/html/conversion.rs b/packages/yew/src/html/conversion.rs index 18f6c14a33f..d0b66ca6a6f 100644 --- a/packages/yew/src/html/conversion.rs +++ b/packages/yew/src/html/conversion.rs @@ -58,15 +58,15 @@ macro_rules! impl_into_prop { } } // implement V -> Option - impl IntoOptPropValue<$to_ty> for $from_ty { - fn into_opt_prop_value(self) -> Option<$to_ty> { + impl IntoPropValue> for $from_ty { + fn into_prop_value(self) -> Option<$to_ty> { let $value = self; Some({ $conversion }) } } // implement Option -> Option - impl IntoOptPropValue<$to_ty> for Option<$from_ty> { - fn into_opt_prop_value(self) -> Option<$to_ty> { + impl IntoPropValue> for Option<$from_ty> { + fn into_prop_value(self) -> Option<$to_ty> { self.map(IntoPropValue::into_prop_value) } } @@ -79,17 +79,15 @@ impl_into_prop!(|value: &'static str| -> String { value.to_owned() }); impl_into_prop!(|value: &'static str| -> Cow<'static, str> { Cow::Borrowed(value) }); impl_into_prop!(|value: String| -> Cow<'static, str> { Cow::Owned(value) }); -/// A trait similar to `Into>` which allows conversion to an optional value of a -/// `Properties` struct. -pub trait IntoOptPropValue { - /// Convert `self` to an optional value of a `Properties` struct. - fn into_opt_prop_value(self) -> Option; -} -impl IntoOptPropValue for T -where - T: IntoPropValue>, -{ - fn into_opt_prop_value(self) -> Option { - self.into_prop_value() +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_str() { + let _: String = "foo".into_prop_value(); + let _: Option = "foo".into_prop_value(); + let _: Cow<'static, str> = "foo".into_prop_value(); + let _: Option> = "foo".into_prop_value(); } } diff --git a/packages/yew/src/html/listener/macros.rs b/packages/yew/src/html/listener/macros.rs index c60dff05889..598f3f1bd6c 100644 --- a/packages/yew/src/html/listener/macros.rs +++ b/packages/yew/src/html/listener/macros.rs @@ -6,7 +6,7 @@ macro_rules! impl_action { pub mod $action { use crate::callback::Callback; #[allow(unused_imports)] - use crate::html::{listener::*, IntoOptPropValue}; + use crate::html::{listener::*, IntoPropValue}; use crate::virtual_dom::Listener; use gloo::events::{EventListener, EventListenerOptions}; use wasm_bindgen::JsValue; @@ -26,8 +26,8 @@ macro_rules! impl_action { } #[doc(hidden)] - pub fn __macro_new(callback: impl IntoOptPropValue>) -> Option> { - let callback = callback.into_opt_prop_value()?; + pub fn __macro_new(callback: impl IntoPropValue>>) -> Option> { + let callback = callback.into_prop_value()?; Some(Rc::new(Self::new(callback))) } } diff --git a/packages/yew/src/virtual_dom/mod.rs b/packages/yew/src/virtual_dom/mod.rs index fd02774af36..5f05bdf9669 100644 --- a/packages/yew/src/virtual_dom/mod.rs +++ b/packages/yew/src/virtual_dom/mod.rs @@ -13,7 +13,7 @@ pub mod vtag; #[doc(hidden)] pub mod vtext; -use crate::html::{AnyScope, IntoOptPropValue, NodeRef}; +use crate::html::{AnyScope, IntoPropValue, NodeRef}; use gloo::events::EventListener; use indexmap::IndexMap; use std::{borrow::Cow, collections::HashMap, fmt, hint::unreachable_unchecked, iter, mem, rc::Rc}; @@ -58,8 +58,8 @@ pub type AttrValue = Cow<'static, str>; pub struct PositionalAttr(pub &'static str, pub Option); impl PositionalAttr { /// Create a positional attribute - pub fn new(key: &'static str, value: impl IntoOptPropValue) -> Self { - Self(key, value.into_opt_prop_value()) + pub fn new(key: &'static str, value: impl IntoPropValue>) -> Self { + Self(key, value.into_prop_value()) } /// Create a boolean attribute. diff --git a/packages/yew/src/virtual_dom/vtag.rs b/packages/yew/src/virtual_dom/vtag.rs index f7fc96b77e7..e0165c8ea5f 100644 --- a/packages/yew/src/virtual_dom/vtag.rs +++ b/packages/yew/src/virtual_dom/vtag.rs @@ -3,7 +3,7 @@ use super::{ AttrValue, Attributes, Key, Listener, Listeners, Patch, PositionalAttr, VDiff, VList, VNode, }; -use crate::html::{AnyScope, IntoOptPropValue, IntoPropValue, NodeRef}; +use crate::html::{AnyScope, IntoPropValue, NodeRef}; use crate::utils::document; use gloo::events::EventListener; use log::warn; @@ -140,15 +140,15 @@ impl VTag { /// Sets `value` for an /// [InputElement](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). - pub fn set_value(&mut self, value: impl IntoOptPropValue) { - self.value = value.into_opt_prop_value(); + pub fn set_value(&mut self, value: impl IntoPropValue>) { + self.value = value.into_prop_value(); } /// Sets `kind` property of an /// [InputElement](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input). /// Same as set `type` attribute. - pub fn set_kind(&mut self, value: impl IntoOptPropValue) { - self.kind = value.into_opt_prop_value(); + pub fn set_kind(&mut self, value: impl IntoPropValue>) { + self.kind = value.into_prop_value(); } #[doc(hidden)]