mirror of
https://github.com/yewstack/yew.git
synced 2025-12-08 21:26:25 +00:00
Add Transformer impls to handle handle Option<T> properties (#878)
* Add Transformer impls to handle handle Option<T> properties * Add test * More tests
This commit is contained in:
parent
ffadafe0c2
commit
3195b50d12
@ -249,6 +249,33 @@ impl<'a> Transformer<&'a str, String> for VComp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> Transformer<T, Option<T>> for VComp {
|
||||||
|
fn transform(from: T) -> Option<T> {
|
||||||
|
Some(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> Transformer<&'a T, Option<T>> for VComp
|
||||||
|
where
|
||||||
|
T: Clone,
|
||||||
|
{
|
||||||
|
fn transform(from: &T) -> Option<T> {
|
||||||
|
Some(from.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Transformer<&'a str, Option<String>> for VComp {
|
||||||
|
fn transform(from: &'a str) -> Option<String> {
|
||||||
|
Some(from.to_owned())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Transformer<Option<&'a str>, Option<String>> for VComp {
|
||||||
|
fn transform(from: Option<&'a str>) -> Option<String> {
|
||||||
|
from.map(|s| s.to_owned())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PartialEq for VComp {
|
impl PartialEq for VComp {
|
||||||
fn eq(&self, other: &VComp) -> bool {
|
fn eq(&self, other: &VComp) -> bool {
|
||||||
self.type_id == other.type_id
|
self.type_id == other.type_id
|
||||||
|
|||||||
@ -127,38 +127,47 @@ error[E0599]: no method named `unknown` found for type `ChildPropertiesBuilder<C
|
|||||||
64 | html! { <Child unknown="unknown" /> };
|
64 | html! { <Child unknown="unknown" /> };
|
||||||
| ^^^^^^^ method not found in `ChildPropertiesBuilder<ChildPropertiesBuilderStep_missing_required_prop_int>`
|
| ^^^^^^^ method not found in `ChildPropertiesBuilder<ChildPropertiesBuilderStep_missing_required_prop_int>`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0277]: the trait bound `yew::virtual_dom::vcomp::VComp: yew::virtual_dom::Transformer<(), std::string::String>` is not satisfied
|
||||||
--> $DIR/html-component-fail.rs:66:33
|
--> $DIR/html-component-fail.rs:66:33
|
||||||
|
|
|
|
||||||
66 | html! { <Child int=1 string={} /> };
|
66 | html! { <Child int=1 string={} /> };
|
||||||
| ^^ expected struct `std::string::String`, found ()
|
| ^^ the trait `yew::virtual_dom::Transformer<(), std::string::String>` is not implemented for `yew::virtual_dom::vcomp::VComp`
|
||||||
|
|
|
|
||||||
= note: expected type `std::string::String`
|
= help: the following implementations were found:
|
||||||
found type `()`
|
<yew::virtual_dom::vcomp::VComp as yew::virtual_dom::Transformer<&'a T, T>>
|
||||||
|
<yew::virtual_dom::vcomp::VComp as yew::virtual_dom::Transformer<&'a T, std::option::Option<T>>>
|
||||||
|
<yew::virtual_dom::vcomp::VComp as yew::virtual_dom::Transformer<&'a str, std::option::Option<std::string::String>>>
|
||||||
|
<yew::virtual_dom::vcomp::VComp as yew::virtual_dom::Transformer<&'a str, std::string::String>>
|
||||||
|
and 3 others
|
||||||
|
= note: required by `yew::virtual_dom::Transformer::transform`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0277]: the trait bound `yew::virtual_dom::vcomp::VComp: yew::virtual_dom::Transformer<{integer}, std::string::String>` is not satisfied
|
||||||
--> $DIR/html-component-fail.rs:67:33
|
--> $DIR/html-component-fail.rs:67:33
|
||||||
|
|
|
|
||||||
67 | html! { <Child int=1 string=3 /> };
|
67 | html! { <Child int=1 string=3 /> };
|
||||||
| ^
|
| ^ the trait `yew::virtual_dom::Transformer<{integer}, std::string::String>` is not implemented for `yew::virtual_dom::vcomp::VComp`
|
||||||
| |
|
|
||||||
| expected struct `std::string::String`, found integer
|
|
||||||
| help: try using a conversion method: `3.to_string()`
|
|
||||||
|
|
|
|
||||||
= note: expected type `std::string::String`
|
= help: the following implementations were found:
|
||||||
found type `{integer}`
|
<yew::virtual_dom::vcomp::VComp as yew::virtual_dom::Transformer<&'a T, T>>
|
||||||
|
<yew::virtual_dom::vcomp::VComp as yew::virtual_dom::Transformer<&'a T, std::option::Option<T>>>
|
||||||
|
<yew::virtual_dom::vcomp::VComp as yew::virtual_dom::Transformer<&'a str, std::option::Option<std::string::String>>>
|
||||||
|
<yew::virtual_dom::vcomp::VComp as yew::virtual_dom::Transformer<&'a str, std::string::String>>
|
||||||
|
and 3 others
|
||||||
|
= note: required by `yew::virtual_dom::Transformer::transform`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0277]: the trait bound `yew::virtual_dom::vcomp::VComp: yew::virtual_dom::Transformer<{integer}, std::string::String>` is not satisfied
|
||||||
--> $DIR/html-component-fail.rs:68:33
|
--> $DIR/html-component-fail.rs:68:33
|
||||||
|
|
|
|
||||||
68 | html! { <Child int=1 string={3} /> };
|
68 | html! { <Child int=1 string={3} /> };
|
||||||
| ^^^
|
| ^^^ the trait `yew::virtual_dom::Transformer<{integer}, std::string::String>` is not implemented for `yew::virtual_dom::vcomp::VComp`
|
||||||
| |
|
|
||||||
| expected struct `std::string::String`, found integer
|
|
||||||
| help: try using a conversion method: `{3}.to_string()`
|
|
||||||
|
|
|
|
||||||
= note: expected type `std::string::String`
|
= help: the following implementations were found:
|
||||||
found type `{integer}`
|
<yew::virtual_dom::vcomp::VComp as yew::virtual_dom::Transformer<&'a T, T>>
|
||||||
|
<yew::virtual_dom::vcomp::VComp as yew::virtual_dom::Transformer<&'a T, std::option::Option<T>>>
|
||||||
|
<yew::virtual_dom::vcomp::VComp as yew::virtual_dom::Transformer<&'a str, std::option::Option<std::string::String>>>
|
||||||
|
<yew::virtual_dom::vcomp::VComp as yew::virtual_dom::Transformer<&'a str, std::string::String>>
|
||||||
|
and 3 others
|
||||||
|
= note: required by `yew::virtual_dom::Transformer::transform`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/html-component-fail.rs:69:30
|
--> $DIR/html-component-fail.rs:69:30
|
||||||
@ -169,16 +178,19 @@ error[E0308]: mismatched types
|
|||||||
= note: expected type `yew::html::NodeRef`
|
= note: expected type `yew::html::NodeRef`
|
||||||
found type `()`
|
found type `()`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0277]: the trait bound `yew::virtual_dom::vcomp::VComp: yew::virtual_dom::Transformer<u32, i32>` is not satisfied
|
||||||
--> $DIR/html-component-fail.rs:71:24
|
--> $DIR/html-component-fail.rs:71:24
|
||||||
|
|
|
|
||||||
71 | html! { <Child int=0u32 /> };
|
71 | html! { <Child int=0u32 /> };
|
||||||
| ^^^^ expected i32, found u32
|
| ^^^^ the trait `yew::virtual_dom::Transformer<u32, i32>` is not implemented for `yew::virtual_dom::vcomp::VComp`
|
||||||
|
|
|
|
||||||
help: you can convert an `u32` to `i32` and panic if the converted value wouldn't fit
|
= help: the following implementations were found:
|
||||||
|
|
<yew::virtual_dom::vcomp::VComp as yew::virtual_dom::Transformer<&'a T, T>>
|
||||||
71 | html! { <Child int=0u32.try_into().unwrap() /> };
|
<yew::virtual_dom::vcomp::VComp as yew::virtual_dom::Transformer<&'a T, std::option::Option<T>>>
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
<yew::virtual_dom::vcomp::VComp as yew::virtual_dom::Transformer<&'a str, std::option::Option<std::string::String>>>
|
||||||
|
<yew::virtual_dom::vcomp::VComp as yew::virtual_dom::Transformer<&'a str, std::string::String>>
|
||||||
|
and 3 others
|
||||||
|
= note: required by `yew::virtual_dom::Transformer::transform`
|
||||||
|
|
||||||
error[E0599]: no method named `string` found for type `ChildPropertiesBuilder<ChildPropertiesBuilderStep_missing_required_prop_int>` in the current scope
|
error[E0599]: no method named `string` found for type `ChildPropertiesBuilder<ChildPropertiesBuilderStep_missing_required_prop_int>` in the current scope
|
||||||
--> $DIR/html-component-fail.rs:72:20
|
--> $DIR/html-component-fail.rs:72:20
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use yew::prelude::*;
|
|
||||||
use yew::html::ChildrenRenderer;
|
use yew::html::ChildrenRenderer;
|
||||||
|
use yew::prelude::*;
|
||||||
use yew::virtual_dom::{VChild, VNode};
|
use yew::virtual_dom::{VChild, VNode};
|
||||||
|
|
||||||
pub struct Generic<G> {
|
pub struct Generic<G> {
|
||||||
@ -13,18 +13,30 @@ impl Component for Generic<String> {
|
|||||||
type Message = ();
|
type Message = ();
|
||||||
type Properties = ();
|
type Properties = ();
|
||||||
|
|
||||||
fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self { unimplemented!() }
|
fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self {
|
||||||
fn update(&mut self, _: Self::Message) -> ShouldRender { unimplemented!() }
|
unimplemented!()
|
||||||
fn view(&self) -> Html { unimplemented!() }
|
}
|
||||||
|
fn update(&mut self, _: Self::Message) -> ShouldRender {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
fn view(&self) -> Html {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Component for Generic<Vec<String>> {
|
impl Component for Generic<Vec<String>> {
|
||||||
type Message = ();
|
type Message = ();
|
||||||
type Properties = ();
|
type Properties = ();
|
||||||
|
|
||||||
fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self { unimplemented!() }
|
fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self {
|
||||||
fn update(&mut self, _: Self::Message) -> ShouldRender { unimplemented!() }
|
unimplemented!()
|
||||||
fn view(&self) -> Html { unimplemented!() }
|
}
|
||||||
|
fn update(&mut self, _: Self::Message) -> ShouldRender {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
fn view(&self) -> Html {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Properties, Default)]
|
#[derive(Clone, Properties, Default)]
|
||||||
@ -39,9 +51,15 @@ impl Component for Container {
|
|||||||
type Message = ();
|
type Message = ();
|
||||||
type Properties = ContainerProperties;
|
type Properties = ContainerProperties;
|
||||||
|
|
||||||
fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self { unimplemented!() }
|
fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self {
|
||||||
fn update(&mut self, _: Self::Message) -> ShouldRender { unimplemented!() }
|
unimplemented!()
|
||||||
fn view(&self) -> Html { unimplemented!() }
|
}
|
||||||
|
fn update(&mut self, _: Self::Message) -> ShouldRender {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
fn view(&self) -> Html {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -76,6 +94,7 @@ pub struct ChildProperties {
|
|||||||
pub string: String,
|
pub string: String,
|
||||||
#[props(required)]
|
#[props(required)]
|
||||||
pub int: i32,
|
pub int: i32,
|
||||||
|
pub opt_str: Option<String>,
|
||||||
pub vec: Vec<i32>,
|
pub vec: Vec<i32>,
|
||||||
pub optional_callback: Option<Callback<()>>,
|
pub optional_callback: Option<Callback<()>>,
|
||||||
}
|
}
|
||||||
@ -85,9 +104,15 @@ impl Component for Child {
|
|||||||
type Message = ();
|
type Message = ();
|
||||||
type Properties = ChildProperties;
|
type Properties = ChildProperties;
|
||||||
|
|
||||||
fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self { unimplemented!() }
|
fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self {
|
||||||
fn update(&mut self, _: Self::Message) -> ShouldRender { unimplemented!() }
|
unimplemented!()
|
||||||
fn view(&self) -> Html { unimplemented!() }
|
}
|
||||||
|
fn update(&mut self, _: Self::Message) -> ShouldRender {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
fn view(&self) -> Html {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AltChild;
|
pub struct AltChild;
|
||||||
@ -95,9 +120,15 @@ impl Component for AltChild {
|
|||||||
type Message = ();
|
type Message = ();
|
||||||
type Properties = ();
|
type Properties = ();
|
||||||
|
|
||||||
fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self { unimplemented!() }
|
fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self {
|
||||||
fn update(&mut self, _: Self::Message) -> ShouldRender { unimplemented!() }
|
unimplemented!()
|
||||||
fn view(&self) -> Html { unimplemented!() }
|
}
|
||||||
|
fn update(&mut self, _: Self::Message) -> ShouldRender {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
fn view(&self) -> Html {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Properties, Default)]
|
#[derive(Clone, Properties, Default)]
|
||||||
@ -112,9 +143,15 @@ impl Component for ChildContainer {
|
|||||||
type Message = ();
|
type Message = ();
|
||||||
type Properties = ChildContainerProperties;
|
type Properties = ChildContainerProperties;
|
||||||
|
|
||||||
fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self { unimplemented!() }
|
fn create(_: Self::Properties, _: ComponentLink<Self>) -> Self {
|
||||||
fn update(&mut self, _: Self::Message) -> ShouldRender { unimplemented!() }
|
unimplemented!()
|
||||||
fn view(&self) -> Html { unimplemented!() }
|
}
|
||||||
|
fn update(&mut self, _: Self::Message) -> ShouldRender {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
fn view(&self) -> Html {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod scoped {
|
mod scoped {
|
||||||
@ -158,6 +195,11 @@ fn compile_pass() {
|
|||||||
<Child int=1 vec={vec![1]} />
|
<Child int=1 vec={vec![1]} />
|
||||||
<Child string={String::from("child")} int=1 />
|
<Child string={String::from("child")} int=1 />
|
||||||
|
|
||||||
|
<Child opt_str="child" int=1 />
|
||||||
|
<Child opt_str=String::from("child") int=1 />
|
||||||
|
<Child opt_str=Some("child") int=1 />
|
||||||
|
<Child opt_str=Some(String::from("child")) int=1 />
|
||||||
|
|
||||||
// backwards compat
|
// backwards compat
|
||||||
<Child: string="child", int=3, />
|
<Child: string="child", int=3, />
|
||||||
</>
|
</>
|
||||||
@ -172,6 +214,7 @@ fn compile_pass() {
|
|||||||
<>
|
<>
|
||||||
<Child int=1 />
|
<Child int=1 />
|
||||||
<Child int=1 optional_callback=Some(Callback::from(|_| ())) />
|
<Child int=1 optional_callback=Some(Callback::from(|_| ())) />
|
||||||
|
<Child int=1 optional_callback=Callback::from(|_| ()) />
|
||||||
<Child int=1 optional_callback=None />
|
<Child int=1 optional_callback=None />
|
||||||
</>
|
</>
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user