Skip to content

Commit d247e3b

Browse files
committed
feat: allow &str and String conversion for Option<Html>
1 parent 0db226a commit d247e3b

1 file changed

Lines changed: 78 additions & 0 deletions

File tree

packages/yew/src/html/conversion/into_prop_value.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,24 @@ macro_rules! impl_into_prop_value_via_display {
298298
self.clone().into_prop_value()
299299
}
300300
}
301+
impl IntoPropValue<Option<VNode>> for $from_ty {
302+
#[inline(always)]
303+
fn into_prop_value(self) -> Option<VNode> {
304+
Some(IntoPropValue::<VNode>::into_prop_value(self))
305+
}
306+
}
307+
impl IntoPropValue<Option<VNode>> for &$from_ty {
308+
#[inline(always)]
309+
fn into_prop_value(self) -> Option<VNode> {
310+
Some(IntoPropValue::<VNode>::into_prop_value(self))
311+
}
312+
}
313+
impl IntoPropValue<Option<VNode>> for Option<$from_ty> {
314+
#[inline(always)]
315+
fn into_prop_value(self) -> Option<VNode> {
316+
self.map(IntoPropValue::<VNode>::into_prop_value)
317+
}
318+
}
301319
};
302320
}
303321

@@ -310,6 +328,18 @@ macro_rules! impl_into_prop_value_via_attr_value {
310328
VText::new(self).into()
311329
}
312330
}
331+
impl IntoPropValue<Option<VNode>> for $from_ty {
332+
#[inline(always)]
333+
fn into_prop_value(self) -> Option<VNode> {
334+
Some(VText::new(self).into())
335+
}
336+
}
337+
impl IntoPropValue<Option<VNode>> for Option<$from_ty> {
338+
#[inline(always)]
339+
fn into_prop_value(self) -> Option<VNode> {
340+
self.map(|v| VText::new(v).into())
341+
}
342+
}
313343
};
314344
}
315345

@@ -368,6 +398,28 @@ mod test {
368398
let _: VNode = Some(true).into_prop_value();
369399
}
370400

401+
#[test]
402+
fn test_into_option_vnode() {
403+
// T -> Option<VNode>
404+
let _: Option<VNode> = "hello".into_prop_value();
405+
let _: Option<VNode> = String::from("hello").into_prop_value();
406+
let _: Option<VNode> = AttrValue::Static("hello").into_prop_value();
407+
let _: Option<VNode> = 42u32.into_prop_value();
408+
let _: Option<VNode> = true.into_prop_value();
409+
// &T -> Option<VNode>
410+
let _: Option<VNode> = (&42u32).into_prop_value();
411+
let _: Option<VNode> = (&true).into_prop_value();
412+
let s = String::from("hello");
413+
let _: Option<VNode> = (&s).into_prop_value();
414+
// Option<T> -> Option<VNode>
415+
let _: Option<VNode> = Some("hello").into_prop_value();
416+
let _: Option<VNode> = Option::<&str>::None.into_prop_value();
417+
let _: Option<VNode> = Some(String::from("hello")).into_prop_value();
418+
let _: Option<VNode> = Option::<String>::None.into_prop_value();
419+
let _: Option<VNode> = Some(42u32).into_prop_value();
420+
let _: Option<VNode> = Some(true).into_prop_value();
421+
}
422+
371423
#[test]
372424
fn test_ref_to_vnode() {
373425
let _: VNode = (&42i32).into_prop_value();
@@ -570,4 +622,30 @@ mod test {
570622
let _ = html! { <Child>{&attr_value}</Child> };
571623
}
572624
}
625+
626+
#[test]
627+
fn test_option_html_prop_compiles() {
628+
use crate::prelude::*;
629+
630+
#[derive(PartialEq, Properties)]
631+
pub struct Props {
632+
pub title: Option<Html>,
633+
}
634+
635+
#[component]
636+
fn Foo(props: &Props) -> Html {
637+
match &props.title {
638+
Some(title) => html! { <h1>{ title.clone() }</h1> },
639+
None => html! {},
640+
}
641+
}
642+
643+
let _ = html! { <Foo title="Title" /> };
644+
645+
let _ = html! { <Foo title={String::from("Title")} /> };
646+
647+
let _ = html! { <Foo title={Some("Title")} /> };
648+
649+
let _ = html! { <Foo title={Option::<Html>::None} /> };
650+
}
573651
}

0 commit comments

Comments
 (0)