diff --git a/packages/core/src/nodes.rs b/packages/core/src/nodes.rs index 0e6738b2b..c05731ee2 100644 --- a/packages/core/src/nodes.rs +++ b/packages/core/src/nodes.rs @@ -108,6 +108,10 @@ pub struct Template<'a> { /// The name of the template. This must be unique across your entire program for template diffing to work properly /// /// If two templates have the same name, it's likely that Dioxus will panic when diffing. + #[cfg_attr( + feature = "serialize", + serde(deserialize_with = "deserialize_string_leaky") + )] pub name: &'a str, /// The list of template nodes that make up the template @@ -120,17 +124,49 @@ pub struct Template<'a> { /// /// These will be one segment shorter than the path sent to the renderer since those paths are relative to the /// topmost element, not the `roots` field. - #[cfg_attr(feature = "serialize", serde(deserialize_with = "deserialize_leaky"))] + #[cfg_attr( + feature = "serialize", + serde(deserialize_with = "deserialize_bytes_leaky") + )] pub node_paths: &'a [&'a [u8]], /// The paths of each dynamic attribute relative to the root of the template /// /// These will be one segment shorter than the path sent to the renderer since those paths are relative to the /// topmost element, not the `roots` field. - #[cfg_attr(feature = "serialize", serde(deserialize_with = "deserialize_leaky"))] + #[cfg_attr( + feature = "serialize", + serde(deserialize_with = "deserialize_bytes_leaky") + )] pub attr_paths: &'a [&'a [u8]], } +#[cfg(feature = "serialize")] +fn deserialize_string_leaky<'a, 'de, D>(deserializer: D) -> Result<&'a str, D::Error> +where + D: serde::Deserializer<'de>, +{ + use serde::Deserialize; + + let deserialized = String::deserialize(deserializer)?; + Ok(&*Box::leak(deserialized.into_boxed_str())) +} + +#[cfg(feature = "serialize")] +fn deserialize_bytes_leaky<'a, 'de, D>(deserializer: D) -> Result<&'a [&'a [u8]], D::Error> +where + D: serde::Deserializer<'de>, +{ + use serde::Deserialize; + + let deserialized = Vec::>::deserialize(deserializer)?; + let deserialized = deserialized + .into_iter() + .map(|v| &*Box::leak(v.into_boxed_slice())) + .collect::>(); + Ok(&*Box::leak(deserialized.into_boxed_slice())) +} + #[cfg(feature = "serialize")] fn deserialize_leaky<'a, 'de, T: serde::Deserialize<'de>, D>( deserializer: D, diff --git a/packages/core/src/virtual_dom.rs b/packages/core/src/virtual_dom.rs index 44f085b09..2c6021ef1 100644 --- a/packages/core/src/virtual_dom.rs +++ b/packages/core/src/virtual_dom.rs @@ -458,6 +458,7 @@ impl VirtualDom { /// The caller must ensure that the template refrences the same dynamic attributes and nodes as the original template. pub fn replace_template(&mut self, template: Template<'static>) { self.templates.insert(template.name, template); + panic!("{:?}", self.templates); // iterating a slab is very inefficient, but this is a rare operation that will only happen during development so it's fine for (_, scope) in &self.scopes { if let Some(RenderReturn::Sync(Ok(sync))) = scope.try_root_node() { diff --git a/packages/rsx/src/lib.rs b/packages/rsx/src/lib.rs index 73e712e3c..a46e7b67a 100644 --- a/packages/rsx/src/lib.rs +++ b/packages/rsx/src/lib.rs @@ -19,7 +19,7 @@ mod hot_reloading_context; mod ifmt; mod node; -use std::{collections::HashMap, hash::Hash}; +use std::{collections::HashMap, fmt::Debug, hash::Hash}; // Re-export the namespaces into each other pub use component::*; @@ -181,6 +181,7 @@ impl<'a, Ctx: HotReloadingContext> ToTokens for TemplateRenderer<'a, Ctx> { }; let spndbg = format!("{:?}", self.roots[0].span()); + println!("spndbg: {}", spndbg); let root_col = spndbg[9..].split("..").next().unwrap(); let root_printer = self.roots.iter().enumerate().map(|(idx, root)| { @@ -226,7 +227,7 @@ impl<'a, Ctx: HotReloadingContext> ToTokens for TemplateRenderer<'a, Ctx> { } } -#[derive(Debug, Default)] +#[derive(Default, Debug)] struct DynamicMapping { attribute_to_idx: HashMap>, last_attribute_idx: usize, @@ -240,7 +241,6 @@ impl DynamicMapping { for node in nodes { new.add_node(node); } - println!("{:#?}", new); new } diff --git a/packages/web/src/hot_reload.rs b/packages/web/src/hot_reload.rs index a48b5ff70..444edd222 100644 --- a/packages/web/src/hot_reload.rs +++ b/packages/web/src/hot_reload.rs @@ -20,6 +20,8 @@ pub(crate) fn init() -> UnboundedReceiver> { pub(crate) fn init() -> UnboundedReceiver> { use std::convert::TryInto; + use web_sys::console; + let window = web_sys::window().unwrap(); let protocol = if window.location().protocol().unwrap() == "https:" { @@ -42,8 +44,10 @@ pub(crate) fn init() -> UnboundedReceiver> { if let Ok(text) = e.data().dyn_into::() { let text: Result = text.try_into(); if let Ok(string) = text { - if let Ok(template) = serde_json::from_str(Box::leak(string.into_boxed_str())) { - _ = tx.unbounded_send(template); + console::log_1(&string.clone().into()); + match serde_json::from_str(Box::leak(string.into_boxed_str())) { + Ok(template) => _ = tx.unbounded_send(template), + Err(e) => console::log_1(&e.to_string().into()), } } } diff --git a/packages/web/src/lib.rs b/packages/web/src/lib.rs index 9c66825c9..f536edb82 100644 --- a/packages/web/src/lib.rs +++ b/packages/web/src/lib.rs @@ -58,6 +58,7 @@ use crate::dom::virtual_event_from_websys_event; pub use crate::util::{use_eval, EvalResult}; use dioxus_core::{Element, ElementId, Scope, VirtualDom}; use futures_util::{pin_mut, FutureExt, StreamExt}; +use web_sys::console; mod cache; mod cfg; @@ -209,6 +210,7 @@ pub async fn run_with_props(root: fn(Scope) -> Element, root_prop futures_util::select! { _ = work => (None, None), new_template = hotreload_rx.next() => { + console::log_1(&"hot reload".into()); (None, new_template) } evt = rx.next() => (evt, None)