diff --git a/examples/server_integration/Cargo.lock b/examples/server_integration/Cargo.lock index 5817eafbc..d22de5602 100644 --- a/examples/server_integration/Cargo.lock +++ b/examples/server_integration/Cargo.lock @@ -458,6 +458,15 @@ dependencies = [ "wasm-bindgen 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "cookie" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "copyless" version = "0.1.2" @@ -1307,6 +1316,7 @@ name = "seed" version = "0.4.1" dependencies = [ "console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "dbg 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "enclose 1.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2002,6 +2012,7 @@ dependencies = [ "checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum console_error_panic_hook 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d976903543e0c48546a91908f21588a680a8c8f984df9a5d69feccb2b2a211" +"checksum cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "888604f00b3db336d2af898ec3c1d5d0ddf5e6d462220f2ededc33a87ac4bbd5" "checksum copyless 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "59de7722d3b5c7b35dd519d617fe5116c9b879a0f145dc5431d78ab1f61d7c23" "checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" "checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" diff --git a/src/dom_types.rs b/src/dom_types.rs index 456bead26..3f1512564 100644 --- a/src/dom_types.rs +++ b/src/dom_types.rs @@ -1430,4 +1430,28 @@ pub mod tests { assert_eq!(expected, get_node_html(&node)); } + + /// Test that `style!` macro accept types that have `to_css_value()` function + #[wasm_bindgen_test] + pub fn to_css_value_in_style() { + let display: &str = "flex"; + let direction: String = "column".to_string(); + let order: Option = None; + let gap: Option<&str> = Some("8px"); + + let style = style![ + St::Display => display, + St::FlexDirection => direction, + St::Order => order, + St::Gap => gap, + ]; + + let mut result_style = Style::empty(); + result_style.add(St::Display, CSSValue::Some("flex".into())); + result_style.add(St::FlexDirection, CSSValue::Some("column".into())); + result_style.add(St::Order, CSSValue::Ignored); + result_style.add(St::Gap, CSSValue::Some("8px".into())); + + assert_eq!(style, result_style) + } } diff --git a/src/dom_types/values.rs b/src/dom_types/values.rs index c48cef0e6..94fc81a9e 100644 --- a/src/dom_types/values.rs +++ b/src/dom_types/values.rs @@ -25,11 +25,42 @@ impl From for CSSValue { } } -// `&` because `style!` macro automatically adds prefix `&` before values for more ergonomic API -// (otherwise it would fail when you use for example a Model's property in View functions as `CSSValue`) -impl From<&CSSValue> for CSSValue { - fn from(value: &CSSValue) -> Self { - value.clone() +// ----------- ToCSSValue impls ------------ + +// impl ToCSSValue for CSSValue +#[doc(hidden)] +pub trait ToCSSValueForCSSValue { + fn to_css_value(self) -> CSSValue; +} + +impl ToCSSValueForCSSValue for CSSValue { + fn to_css_value(self) -> CSSValue { + self + } +} + +// impl ToCSSValue for T +#[doc(hidden)] +pub trait ToCSSValueForToString { + fn to_css_value(&self) -> CSSValue; +} + +impl ToCSSValueForToString for T { + fn to_css_value(&self) -> CSSValue { + CSSValue::Some(self.to_string()) + } +} + +// impl ToCSSValue for Option +#[doc(hidden)] +pub trait ToCSSValueForOptionToString { + fn to_css_value(&self) -> CSSValue; +} + +impl ToCSSValueForOptionToString for Option { + fn to_css_value(&self) -> CSSValue { + self.as_ref() + .map_or(CSSValue::Ignored, |t| CSSValue::Some(t.to_string())) } } diff --git a/src/shortcuts.rs b/src/shortcuts.rs index 4ed1695dc..e97408a27 100644 --- a/src/shortcuts.rs +++ b/src/shortcuts.rs @@ -243,17 +243,20 @@ macro_rules! id { }; } +// reference for workaround used by style! macro +// (https://github.com/dtolnay/case-studies/blob/master/autoref-specialization/README.md) /// Provide a shortcut for creating styles. #[macro_export] macro_rules! style { { $($key:expr => $value:expr $(;)?$(,)?)* } => { { + #[allow(unused_imports)] + use $crate::dom_types::values::{ + ToCSSValueForCSSValue, ToCSSValueForOptionToString, ToCSSValueForToString + }; let mut vals = IndexMap::new(); $( - // We can handle arguments of multiple types by using this: - // Strings, &strs, bools, numbers etc. - // And cases like `CSSValue::Ignored`. - vals.insert($key.into(), (&$value).into()); + vals.insert($key.into(), ($value).to_css_value()); )* $crate::dom_types::Style::new(vals) } diff --git a/src/vdom.rs b/src/vdom.rs index 4709c0596..32d332a62 100644 --- a/src/vdom.rs +++ b/src/vdom.rs @@ -228,9 +228,7 @@ impl + 'static, GMs: 'static> App { /// an initial render. pub fn run(self) -> Self { // Bootstrap the virtual DOM. - self.data - .main_el_vdom - .replace(Some(self.bootstrap_vdom())); + self.data.main_el_vdom.replace(Some(self.bootstrap_vdom())); // Update the state on page load, based // on the starting URL. Must be set up on the server as well.