diff --git a/packages/yew/src/html/classes.rs b/packages/yew/src/html/classes.rs index 37577d4a0f6..6c57e9b4de5 100644 --- a/packages/yew/src/html/classes.rs +++ b/packages/yew/src/html/classes.rs @@ -76,7 +76,7 @@ impl IntoPropValue for Classes { None => unsafe { unreachable_unchecked() }, } } else { - AttrValue::Owned(self.to_string()) + AttrValue::Rc(Rc::from(self.to_string())) } } } diff --git a/packages/yew/src/html/conversion.rs b/packages/yew/src/html/conversion.rs index a2a7f7e4ef8..aa0b6c7d077 100644 --- a/packages/yew/src/html/conversion.rs +++ b/packages/yew/src/html/conversion.rs @@ -1,13 +1,10 @@ use super::{Component, NodeRef, Scope}; use crate::virtual_dom::AttrValue; -use std::{borrow::Cow, rc::Rc}; +use std::rc::Rc; /// Marker trait for types that the [`html!`](macro@crate::html) macro may clone implicitly. pub trait ImplicitClone: Clone {} -// this is only implemented because there's no way to avoid cloning this value -impl ImplicitClone for Cow<'static, str> {} - impl ImplicitClone for Option {} impl ImplicitClone for Rc {} @@ -15,6 +12,20 @@ impl ImplicitClone for NodeRef {} impl ImplicitClone for Scope {} // TODO there are still a few missing +macro_rules! impl_implicit_clone { + ($($ty:ty),+ $(,)?) => { + $(impl ImplicitClone for $ty {})* + }; +} + +#[rustfmt::skip] +impl_implicit_clone!( + u8, u16, u32, u64, u128, + i8, i16, i32, i64, i128, + f32, f64, + &'static str, +); + /// A trait similar to `Into` which allows conversion to a value of a `Properties` struct. pub trait IntoPropValue { /// Convert `self` to a value of a `Properties` struct. @@ -85,7 +96,7 @@ macro_rules! impl_into_prop { impl_into_prop!(|value: &'static str| -> String { value.to_owned() }); impl_into_prop!(|value: &'static str| -> AttrValue { AttrValue::Static(value) }); -impl_into_prop!(|value: String| -> AttrValue { AttrValue::Owned(value) }); +impl_into_prop!(|value: String| -> AttrValue { AttrValue::Rc(Rc::from(value)) }); impl_into_prop!(|value: Rc| -> AttrValue { AttrValue::Rc(value) }); #[cfg(test)] diff --git a/packages/yew/src/virtual_dom/mod.rs b/packages/yew/src/virtual_dom/mod.rs index 94e637c57cd..898d2517928 100644 --- a/packages/yew/src/virtual_dom/mod.rs +++ b/packages/yew/src/virtual_dom/mod.rs @@ -52,8 +52,6 @@ use std::rc::Rc; pub enum AttrValue { /// String living for `'static` Static(&'static str), - /// Owned string - Owned(String), /// Reference counted string Rc(Rc), } @@ -64,7 +62,6 @@ impl Deref for AttrValue { fn deref(&self) -> &Self::Target { match self { AttrValue::Static(s) => *s, - AttrValue::Owned(s) => s.as_str(), AttrValue::Rc(s) => &*s, } } @@ -78,7 +75,7 @@ impl From<&'static str> for AttrValue { impl From for AttrValue { fn from(s: String) -> Self { - AttrValue::Owned(s) + AttrValue::Rc(Rc::from(s)) } } @@ -101,7 +98,6 @@ impl Clone for AttrValue { fn clone(&self) -> Self { match self { AttrValue::Static(s) => AttrValue::Static(s), - AttrValue::Owned(s) => AttrValue::Owned(s.clone()), AttrValue::Rc(s) => AttrValue::Rc(Rc::clone(s)), } } @@ -117,7 +113,6 @@ impl fmt::Display for AttrValue { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { AttrValue::Static(s) => write!(f, "{}", s), - AttrValue::Owned(s) => write!(f, "{}", s), AttrValue::Rc(s) => write!(f, "{}", s), } } @@ -138,7 +133,6 @@ impl AttrValue { pub fn into_string(self) -> String { match self { AttrValue::Static(s) => (*s).to_owned(), - AttrValue::Owned(s) => s, AttrValue::Rc(mut rc) => { if let Some(s) = Rc::get_mut(&mut rc) { (*s).to_owned() @@ -159,9 +153,6 @@ mod tests_attr_value { let av = AttrValue::Static("str"); assert_eq!(av.into_string(), "str"); - let av = AttrValue::Owned("String".to_string()); - assert_eq!(av.into_string(), "String"); - let av = AttrValue::Rc("Rc".into()); assert_eq!(av.into_string(), "Rc"); } @@ -176,25 +167,17 @@ mod tests_attr_value { let av = AttrValue::from(Cow::from("BorrowedCow")); assert_eq!(av.into_string(), "BorrowedCow"); - - let av = AttrValue::from(Cow::from("OwnedCow".to_string())); - assert_eq!(av.into_string(), "OwnedCow"); } #[test] fn test_equality() { // construct 3 AttrValue with same embedded value; expectation is that all are equal - let a = AttrValue::Owned("same".to_string()); - let b = AttrValue::Static("same"); - let c = AttrValue::Rc("same".into()); + let a = AttrValue::Static("same"); + let b = AttrValue::Rc("same".into()); assert_eq!(a, b); - assert_eq!(b, c); - assert_eq!(a, c); assert_eq!(a, b); - assert_eq!(b, c); - assert_eq!(a, c); } }