Skip to content

Commit

Permalink
Remove ToHtml trait (#3453)
Browse files Browse the repository at this point in the history
* remove ToHtml trait

* re-add display impls

* make Vec::clone expilit

* fix doc

* fix conflicting impls

Into<Html> and Display can't be implemented on the same type

* update docs

* blanket impl won't work here

* bring back `Vec<VNode>: IntoPropValue<VNode>`

* macro tests

* Revert "fix conflicting impls"

This reverts commit 52f3c1f.
These impls are fine now

* make examples compile

* .clone() should be before .into()

* Rc VList

* Make use of ImplicitClone and AttrValue in example

(There is more work to do but it's complicated so I will do it in
another PR)

* Impl ImplicitClone on VChild

---------

Co-authored-by: Cecile Tonglet <[email protected]>
  • Loading branch information
ranile and cecton authored Oct 28, 2023
1 parent 7f45af3 commit 0eb167a
Show file tree
Hide file tree
Showing 16 changed files with 168 additions and 293 deletions.
5 changes: 3 additions & 2 deletions examples/function_todomvc/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::rc::Rc;

use serde::{Deserialize, Serialize};
use strum_macros::{Display, EnumIter};
use yew::html::IntoPropValue;
use yew::prelude::*;

#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
Expand Down Expand Up @@ -42,8 +43,8 @@ impl Filter {
}
}

impl ToHtml for Filter {
fn to_html(&self) -> Html {
impl IntoPropValue<Html> for Filter {
fn into_prop_value(self) -> Html {
html! {<>{self.to_string()}</>}
}
}
Expand Down
2 changes: 1 addition & 1 deletion examples/nested_list/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub struct Props {
#[prop_or_default]
pub hide: bool,
pub on_hover: Callback<Hovered>,
pub name: String,
pub name: AttrValue,
#[prop_or_default]
pub children: Children,
}
Expand Down
5 changes: 2 additions & 3 deletions examples/nested_list/src/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,8 @@ impl List {
.filter(|c| !c.props.hide)
.enumerate()
.map(|(i, mut c)| {
let mut props = (*c.props).clone();
props.name = format!("#{} - {}", i + 1, props.name);
c.props = Rc::new(props);
let props = Rc::make_mut(&mut c.props);
props.name = format!("#{} - {}", i + 1, props.name).into();
c
})
.collect::<Html>()
Expand Down
12 changes: 7 additions & 5 deletions examples/nested_list/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::fmt;
use std::ops::Deref;
use std::rc::Rc;

use yew::html::{ImplicitClone, Scope};
use yew::html::{ImplicitClone, IntoPropValue, Scope};
use yew::prelude::*;

pub struct WeakComponentLink<COMP: Component>(Rc<RefCell<Option<Scope<COMP>>>>);
Expand Down Expand Up @@ -40,14 +40,16 @@ impl<COMP: Component> PartialEq for WeakComponentLink<COMP> {
}
}

#[derive(Debug)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Hovered {
Header,
Item(String),
Item(AttrValue),
List,
None,
}

impl ImplicitClone for Hovered {}

impl fmt::Display for Hovered {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
Expand All @@ -63,8 +65,8 @@ impl fmt::Display for Hovered {
}
}

impl ToHtml for Hovered {
fn to_html(&self) -> yew::Html {
impl IntoPropValue<Html> for &Hovered {
fn into_prop_value(self) -> Html {
html! {<>{self.to_string()}</>}
}
}
Expand Down
2 changes: 1 addition & 1 deletion examples/timer/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ impl Component for App {
{ &self.time }
</div>
<div id="messages">
{ for self.messages.iter().map(|message| html! { <p>{ message }</p> }) }
{ for self.messages.iter().map(|message| html! { <p>{ *message }</p> }) }
</div>
</div>
</>
Expand Down
2 changes: 1 addition & 1 deletion examples/timer_functional/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ fn App() -> Html {
.iter()
.map(|message| {
key += 1;
html! { <p key={ key }>{ message }</p> }
html! { <p key={ key }>{ *message }</p> }
})
.collect();

Expand Down
5 changes: 3 additions & 2 deletions examples/todomvc/src/state.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use serde_derive::{Deserialize, Serialize};
use strum_macros::{Display, EnumIter};
use yew::html::IntoPropValue;
use yew::prelude::*;

#[derive(Debug, Serialize, Deserialize)]
Expand Down Expand Up @@ -142,8 +143,8 @@ impl Filter {
}
}

impl ToHtml for Filter {
fn to_html(&self) -> yew::Html {
impl IntoPropValue<Html> for Filter {
fn into_prop_value(self) -> yew::Html {
html! { <>{self.to_string()}</> }
}
}
15 changes: 4 additions & 11 deletions packages/yew-macro/tests/html_macro/component-fail.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -463,16 +463,7 @@ error[E0277]: the trait bound `(): IntoPropValue<String>` is not satisfied
| |
| required by a bound introduced by this call
|
= help: the following other types implement trait `IntoPropValue<T>`:
<&'static [(K, V)] as IntoPropValue<implicit_clone::unsync::IMap<K, V>>>
<&'static [T] as IntoPropValue<implicit_clone::unsync::IArray<T>>>
<&'static str as IntoPropValue<Classes>>
<&'static str as IntoPropValue<Option<String>>>
<&'static str as IntoPropValue<Option<implicit_clone::unsync::IString>>>
<&'static str as IntoPropValue<String>>
<&'static str as IntoPropValue<implicit_clone::unsync::IString>>
<&T as IntoPropValue<Option<T>>>
and $N others
= help: the trait `IntoPropValue<VNode>` is implemented for `()`
note: required by a bound in `ChildPropertiesBuilder::string`
--> tests/html_macro/component-fail.rs:4:17
|
Expand Down Expand Up @@ -706,7 +697,9 @@ error[E0277]: the trait bound `yew::virtual_dom::VText: IntoPropValue<ChildrenRe
117 | html! { <ChildContainer>{ "Not allowed" }</ChildContainer> };
| ^^^^^^^^^^^^^^ the trait `IntoPropValue<ChildrenRenderer<VChild<Child>>>` is not implemented for `yew::virtual_dom::VText`
|
= help: the trait `IntoPropValue<ChildrenRenderer<VNode>>` is implemented for `yew::virtual_dom::VText`
= help: the following other types implement trait `IntoPropValue<T>`:
<yew::virtual_dom::VText as IntoPropValue<ChildrenRenderer<VNode>>>
<yew::virtual_dom::VText as IntoPropValue<VNode>>
note: required by a bound in `ChildContainerPropertiesBuilder::children`
--> tests/html_macro/component-fail.rs:24:17
|
Expand Down
62 changes: 10 additions & 52 deletions packages/yew-macro/tests/html_macro/element-fail.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -434,50 +434,23 @@ error[E0277]: the trait bound `(): IntoPropValue<Option<implicit_clone::unsync::
43 | html! { <input type={()} /> };
| ^^ the trait `IntoPropValue<Option<implicit_clone::unsync::IString>>` is not implemented for `()`
|
= help: the following other types implement trait `IntoPropValue<T>`:
<&'static [(K, V)] as IntoPropValue<implicit_clone::unsync::IMap<K, V>>>
<&'static [T] as IntoPropValue<implicit_clone::unsync::IArray<T>>>
<&'static str as IntoPropValue<Classes>>
<&'static str as IntoPropValue<Option<String>>>
<&'static str as IntoPropValue<Option<implicit_clone::unsync::IString>>>
<&'static str as IntoPropValue<String>>
<&'static str as IntoPropValue<implicit_clone::unsync::IString>>
<&T as IntoPropValue<Option<T>>>
and $N others
= help: the trait `IntoPropValue<VNode>` is implemented for `()`

error[E0277]: the trait bound `(): IntoPropValue<Option<implicit_clone::unsync::IString>>` is not satisfied
--> tests/html_macro/element-fail.rs:44:27
|
44 | html! { <input value={()} /> };
| ^^ the trait `IntoPropValue<Option<implicit_clone::unsync::IString>>` is not implemented for `()`
|
= help: the following other types implement trait `IntoPropValue<T>`:
<&'static [(K, V)] as IntoPropValue<implicit_clone::unsync::IMap<K, V>>>
<&'static [T] as IntoPropValue<implicit_clone::unsync::IArray<T>>>
<&'static str as IntoPropValue<Classes>>
<&'static str as IntoPropValue<Option<String>>>
<&'static str as IntoPropValue<Option<implicit_clone::unsync::IString>>>
<&'static str as IntoPropValue<String>>
<&'static str as IntoPropValue<implicit_clone::unsync::IString>>
<&T as IntoPropValue<Option<T>>>
and $N others
= help: the trait `IntoPropValue<VNode>` is implemented for `()`

error[E0277]: the trait bound `(): IntoPropValue<Option<implicit_clone::unsync::IString>>` is not satisfied
--> tests/html_macro/element-fail.rs:45:22
|
45 | html! { <a href={()} /> };
| ^^ the trait `IntoPropValue<Option<implicit_clone::unsync::IString>>` is not implemented for `()`
|
= help: the following other types implement trait `IntoPropValue<T>`:
<&'static [(K, V)] as IntoPropValue<implicit_clone::unsync::IMap<K, V>>>
<&'static [T] as IntoPropValue<implicit_clone::unsync::IArray<T>>>
<&'static str as IntoPropValue<Classes>>
<&'static str as IntoPropValue<Option<String>>>
<&'static str as IntoPropValue<Option<implicit_clone::unsync::IString>>>
<&'static str as IntoPropValue<String>>
<&'static str as IntoPropValue<implicit_clone::unsync::IString>>
<&T as IntoPropValue<Option<T>>>
and $N others
= help: the trait `IntoPropValue<VNode>` is implemented for `()`

error[E0277]: the trait bound `NotToString: IntoPropValue<Option<implicit_clone::unsync::IString>>` is not satisfied
--> tests/html_macro/element-fail.rs:46:28
Expand All @@ -493,7 +466,7 @@ error[E0277]: the trait bound `NotToString: IntoPropValue<Option<implicit_clone:
<&'static str as IntoPropValue<Option<implicit_clone::unsync::IString>>>
<&'static str as IntoPropValue<String>>
<&'static str as IntoPropValue<implicit_clone::unsync::IString>>
<&T as IntoPropValue<Option<T>>>
<&String as IntoPropValue<VNode>>
and $N others

error[E0277]: the trait bound `Option<NotToString>: IntoPropValue<Option<implicit_clone::unsync::IString>>` is not satisfied
Expand All @@ -510,6 +483,7 @@ error[E0277]: the trait bound `Option<NotToString>: IntoPropValue<Option<implici
<Option<Rc<str>> as IntoPropValue<Option<implicit_clone::unsync::IString>>>
<Option<String> as IntoPropValue<Option<implicit_clone::unsync::IString>>>
<Option<VChild<T>> as IntoPropValue<Option<ChildrenRenderer<C>>>>
<Option<VNode> as IntoPropValue<VNode>>

error[E0277]: the trait bound `Option<{integer}>: IntoPropValue<Option<implicit_clone::unsync::IString>>` is not satisfied
--> tests/html_macro/element-fail.rs:48:22
Expand All @@ -525,6 +499,7 @@ error[E0277]: the trait bound `Option<{integer}>: IntoPropValue<Option<implicit_
<Option<Rc<str>> as IntoPropValue<Option<implicit_clone::unsync::IString>>>
<Option<String> as IntoPropValue<Option<implicit_clone::unsync::IString>>>
<Option<VChild<T>> as IntoPropValue<Option<ChildrenRenderer<C>>>>
<Option<VNode> as IntoPropValue<VNode>>

error[E0277]: expected a `Fn<(MouseEvent,)>` closure, found `{integer}`
--> tests/html_macro/element-fail.rs:51:28
Expand Down Expand Up @@ -613,16 +588,7 @@ error[E0277]: the trait bound `(): IntoPropValue<yew::NodeRef>` is not satisfied
56 | html! { <input ref={()} /> };
| ^^ the trait `IntoPropValue<yew::NodeRef>` is not implemented for `()`
|
= help: the following other types implement trait `IntoPropValue<T>`:
<&'static [(K, V)] as IntoPropValue<implicit_clone::unsync::IMap<K, V>>>
<&'static [T] as IntoPropValue<implicit_clone::unsync::IArray<T>>>
<&'static str as IntoPropValue<Classes>>
<&'static str as IntoPropValue<Option<String>>>
<&'static str as IntoPropValue<Option<implicit_clone::unsync::IString>>>
<&'static str as IntoPropValue<String>>
<&'static str as IntoPropValue<implicit_clone::unsync::IString>>
<&T as IntoPropValue<Option<T>>>
and $N others
= help: the trait `IntoPropValue<VNode>` is implemented for `()`
= note: this error originates in the macro `html` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `Option<yew::NodeRef>: IntoPropValue<yew::NodeRef>` is not satisfied
Expand All @@ -639,6 +605,7 @@ error[E0277]: the trait bound `Option<yew::NodeRef>: IntoPropValue<yew::NodeRef>
<Option<Rc<str>> as IntoPropValue<Option<implicit_clone::unsync::IString>>>
<Option<String> as IntoPropValue<Option<implicit_clone::unsync::IString>>>
<Option<VChild<T>> as IntoPropValue<Option<ChildrenRenderer<C>>>>
<Option<VNode> as IntoPropValue<VNode>>
= note: this error originates in the macro `html` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: expected a `Fn<(MouseEvent,)>` closure, found `yew::Callback<String>`
Expand Down Expand Up @@ -682,7 +649,7 @@ error[E0277]: the trait bound `NotToString: IntoPropValue<Option<implicit_clone:
<&'static str as IntoPropValue<Option<implicit_clone::unsync::IString>>>
<&'static str as IntoPropValue<String>>
<&'static str as IntoPropValue<implicit_clone::unsync::IString>>
<&T as IntoPropValue<Option<T>>>
<&String as IntoPropValue<VNode>>
and $N others

error[E0277]: the trait bound `(): IntoPropValue<yew::NodeRef>` is not satisfied
Expand All @@ -691,16 +658,7 @@ error[E0277]: the trait bound `(): IntoPropValue<yew::NodeRef>` is not satisfied
62 | html! { <input ref={()} /> };
| ^^ the trait `IntoPropValue<yew::NodeRef>` is not implemented for `()`
|
= help: the following other types implement trait `IntoPropValue<T>`:
<&'static [(K, V)] as IntoPropValue<implicit_clone::unsync::IMap<K, V>>>
<&'static [T] as IntoPropValue<implicit_clone::unsync::IArray<T>>>
<&'static str as IntoPropValue<Classes>>
<&'static str as IntoPropValue<Option<String>>>
<&'static str as IntoPropValue<Option<implicit_clone::unsync::IString>>>
<&'static str as IntoPropValue<String>>
<&'static str as IntoPropValue<implicit_clone::unsync::IString>>
<&T as IntoPropValue<Option<T>>>
and $N others
= help: the trait `IntoPropValue<VNode>` is implemented for `()`
= note: this error originates in the macro `html` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0277]: the trait bound `implicit_clone::unsync::IString: From<{integer}>` is not satisfied
Expand Down
3 changes: 2 additions & 1 deletion packages/yew/src/html/component/children.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,11 @@ where
/// ```
/// # let children = Children::new(Vec::new());
/// # use yew::{classes, html, Children};
/// # let _ =
/// children.map(|children| {
/// html! {
/// <div class={classes!("container")}>
/// {children}
/// {children.clone()}
/// </div>
/// }
/// })
Expand Down
Loading

0 comments on commit 0eb167a

Please sign in to comment.