From 28fba42e7e8ed9ceddc8024860cfa3b0d7a80cf3 Mon Sep 17 00:00:00 2001 From: Jon Kelley Date: Sun, 25 Sep 2022 01:05:16 -0700 Subject: [PATCH] feat: add an unhygenic render macro (#556) * feat: add an unhygenic render macro * chore: use render instead of rsx!(cx, --- .../__unused/advanced-guides/11-arena-memo.md | 2 +- .../en/__unused/advanced-guides/12-signals.md | 2 +- docs/reference/src/guide/rsx_in_depth.md | 24 +++--- .../reference/src/guide/rsx_in_depth_pt-br.md | 24 +++--- examples/file_explorer.rs | 78 ++++++++++--------- examples/svg.rs | 8 +- notes/README.md | 4 +- packages/core-macro/src/lib.rs | 20 +++++ packages/core/README.md | 2 +- packages/core/src/events.rs | 2 +- packages/core/src/scopes.rs | 10 +-- packages/core/src/virtual_dom.rs | 8 +- packages/dioxus/benches/jsframework.rs | 2 +- packages/dioxus/src/lib.rs | 2 +- packages/dioxus/tests/diffing.rs | 2 +- packages/dioxus/tests/earlyabort.rs | 2 +- packages/dioxus/tests/miri_stress.rs | 33 ++++---- packages/dioxus/tests/passthru.rs | 2 +- packages/dioxus/tests/vdom_rebuild.rs | 2 +- .../tests/called_minimally_on_build.rs | 2 +- .../native-core-macro/tests/change_nodes.rs | 4 +- .../native-core-macro/tests/initial_build.rs | 4 +- .../tests/peristant_iterator.rs | 8 +- .../native-core-macro/tests/update_state.rs | 8 +- packages/rsx/src/lib.rs | 41 +++------- .../rsx_interpreter/src/captuered_context.rs | 5 +- packages/rsx_interpreter/tests/render.rs | 16 ++-- packages/web/src/lib.rs | 4 +- 28 files changed, 158 insertions(+), 163 deletions(-) diff --git a/docs/guide/src/en/__unused/advanced-guides/11-arena-memo.md b/docs/guide/src/en/__unused/advanced-guides/11-arena-memo.md index 0c98fc255..ca44a6b7e 100644 --- a/docs/guide/src/en/__unused/advanced-guides/11-arena-memo.md +++ b/docs/guide/src/en/__unused/advanced-guides/11-arena-memo.md @@ -32,7 +32,7 @@ static TestComponent: Component = |cx|{ #[inline_props] fn test_component(cx: Scope, name: String) -> Element { - rsx!(cx, "Hello, {name}") + render!("Hello, {name}") } ``` diff --git a/docs/guide/src/en/__unused/advanced-guides/12-signals.md b/docs/guide/src/en/__unused/advanced-guides/12-signals.md index aa20d43ee..6b0f3ffea 100644 --- a/docs/guide/src/en/__unused/advanced-guides/12-signals.md +++ b/docs/guide/src/en/__unused/advanced-guides/12-signals.md @@ -98,7 +98,7 @@ Sometimes you want a signal to propagate across your app, either through far-awa const TITLE: Atom = || "".to_string(); const Provider: Component = |cx|{ let title = use_signal(&cx, &TITLE); - rsx!(cx, input { value: title }) + render!(input { value: title }) }; ``` diff --git a/docs/reference/src/guide/rsx_in_depth.md b/docs/reference/src/guide/rsx_in_depth.md index ac0e2e498..75e1f4a98 100644 --- a/docs/reference/src/guide/rsx_in_depth.md +++ b/docs/reference/src/guide/rsx_in_depth.md @@ -53,14 +53,14 @@ Commas are entirely optional, but might be useful to delineate between elements The `render` function provides an **extremely efficient** allocator for VNodes and text, so try not to use the `format!` macro in your components. Rust's default `ToString` methods pass through the global allocator, but all text in components is allocated inside a manually-managed Bump arena. To push you in the right direction, all text-based attributes take `std::fmt::Arguments` directly, so you'll want to reach for `format_args!` when the built-in `f-string` interpolation just doesn't cut it. -### Ignoring `cx.render` with `rsx!(cx, ...)` +### Ignoring `cx.render` with `render!(...)` Sometimes, writing `cx.render` is a hassle. The `rsx! macro will accept any token followed by a comma as the target to call "render" on: ```rust cx.render(rsx!( div {} )) // becomes -rsx!(cx, div {}) +render!(div {}) ``` ### Conditional Rendering @@ -70,9 +70,9 @@ Sometimes, you might not want to render an element given a condition. The rsx! m ```rust rsx!({ if enabled { - rsx!(cx, div {"enabled"}) + render!(div {"enabled"}) } else { - rsx!(cx, li {"disabled"}) + render!(li {"disabled"}) } }) ``` @@ -96,8 +96,8 @@ match case { // the nodes must be rendered first match case { - true => rsx!(cx, div {}), - false => rsx!(cx, div {}) + true => render!(div {}), + false => render!(div {}) } ``` @@ -121,10 +121,10 @@ Sometimes, it makes sense to render VNodes into a list: let mut items = vec![]; for _ in 0..5 { - items.push(rsx!(cx, li {} )) + items.push(render!(li {} )) } -rsx!(cx, {items} ) +render!({items} ) ``` #### Lists and Keys @@ -137,7 +137,7 @@ In these cases, it is vitally important to specify a "key" alongside the element ```rust fn render_list(cx: Scope, items: HashMap) -> DomTree { - rsx!(cx, ul { + render!(ul { {items.iter().map(|key, item| { li { key: key, @@ -209,9 +209,9 @@ cx.render(rsx!{ // rsx! is lazy, and the underlying closures cannot have the same type // Rendering produces the VNode type {match rand::gen_range::(1..3) { - 1 => rsx!(cx, h1 { "big" }) - 2 => rsx!(cx, h2 { "medium" }) - _ => rsx!(cx, h3 { "small" }) + 1 => render!(h1 { "big" }) + 2 => render!(h2 { "medium" }) + _ => render!(h3 { "small" }) }} // Optionals diff --git a/docs/reference/src/guide/rsx_in_depth_pt-br.md b/docs/reference/src/guide/rsx_in_depth_pt-br.md index 0a1033e92..82c4f9298 100644 --- a/docs/reference/src/guide/rsx_in_depth_pt-br.md +++ b/docs/reference/src/guide/rsx_in_depth_pt-br.md @@ -53,14 +53,14 @@ As vírgulas são totalmente opcionais, mas podem ser úteis para delinear entre A função `render` fornece um alocador **extremamente eficiente** para `VNodes` e `text`, então tente não usar a macro `format!` em seus componentes. Os métodos `ToString` padrão do Rust passam pelo alocador global, mas todo o texto nos componentes é alocado dentro de uma ""arena Bump"" gerenciada manualmente. Para levá-lo na direção certa, todos os atributos baseados em texto recebem `std::fmt::Arguments` diretamente, então você vai querer usar `format_args!` quando a interpolação interna `f-string` simplesmente não funcionar. -### Ignorando `cx.render` com `rsx!(cx, ...)` +### Ignorando `cx.render` com `render!(...)` Às vezes, escrever `cx.render` é um aborrecimento. O `rsx!` macro aceitará qualquer token seguido por uma vírgula como destino para chamar "render" em: ```rust cx.render(rsx!( div {} )) // becomes -rsx!(cx, div {}) +render!(div {}) ``` ### Renderização Condicional @@ -70,9 +70,9 @@ rsx!(cx, div {}) ```rust rsx!({ if enabled { - rsx!(cx, div {"enabled"}) + render!(div {"enabled"}) } else { - rsx!(cx, li {"disabled"}) + render!(li {"disabled"}) } }) ``` @@ -96,8 +96,8 @@ match case { // the nodes must be rendered first match case { - true => rsx!(cx, div {}), - false => rsx!(cx, div {}) + true => render!(div {}), + false => render!(div {}) } ``` @@ -121,10 +121,10 @@ cx.render(rsx!{ let mut items = vec![]; for _ in 0..5 { - items.push(rsx!(cx, li {} )) + items.push(render!(li {} )) } -rsx!(cx, {items} ) +render!({items} ) ``` #### Listas e chaves @@ -137,7 +137,7 @@ Nesses casos, é de vital importância especificar uma "chave" ao lado do elemen ```rust fn render_list(cx: Scope, items: HashMap) -> DomTree { - rsx!(cx, ul { + render!(ul { {items.iter().map(|key, item| { li { key: key, @@ -209,9 +209,9 @@ cx.render(rsx!{ // rsx! is lazy, and the underlying closures cannot have the same type // Rendering produces the VNode type {match rand::gen_range::(1..3) { - 1 => rsx!(cx, h1 { "big" }) - 2 => rsx!(cx, h2 { "medium" }) - _ => rsx!(cx, h3 { "small" }) + 1 => render!(h1 { "big" }) + 2 => render!(h2 { "medium" }) + _ => render!(h3 { "small" }) }} // Optionals diff --git a/examples/file_explorer.rs b/examples/file_explorer.rs index c1bbeeaaf..e0acb4ae6 100644 --- a/examples/file_explorer.rs +++ b/examples/file_explorer.rs @@ -21,46 +21,48 @@ fn main() { fn app(cx: Scope) -> Element { let files = use_ref(&cx, Files::new); - rsx!(cx, div { - link { href:"https://fonts.googleapis.com/icon?family=Material+Icons", rel:"stylesheet", } - style { include_str!("./assets/fileexplorer.css") } - header { - i { class: "material-icons icon-menu", "menu" } - h1 { "Files: ", files.read().current() } - span { } - i { class: "material-icons", onclick: move |_| files.write().go_up(), "logout" } - } - main { - files.read().path_names.iter().enumerate().map(|(dir_id, path)| { - let path_end = path.split('/').last().unwrap_or(path.as_str()); - let icon_type = if path_end.contains('.') { - "description" - } else { - "folder" - }; - rsx! ( - div { - class: "folder", - key: "{path}", - i { class: "material-icons", - onclick: move |_| files.write().enter_dir(dir_id), - "{icon_type}" - p { class: "cooltip", "0 folders / 0 files" } + render! { + div { + link { href:"https://fonts.googleapis.com/icon?family=Material+Icons", rel:"stylesheet", } + style { include_str!("./assets/fileexplorer.css") } + header { + i { class: "material-icons icon-menu", "menu" } + h1 { "Files: ", files.read().current() } + span { } + i { class: "material-icons", onclick: move |_| files.write().go_up(), "logout" } + } + main { + files.read().path_names.iter().enumerate().map(|(dir_id, path)| { + let path_end = path.split('/').last().unwrap_or(path.as_str()); + let icon_type = if path_end.contains('.') { + "description" + } else { + "folder" + }; + rsx! ( + div { + class: "folder", + key: "{path}", + i { class: "material-icons", + onclick: move |_| files.write().enter_dir(dir_id), + "{icon_type}" + p { class: "cooltip", "0 folders / 0 files" } + } + h1 { "{path_end}" } } - h1 { "{path_end}" } - } - ) - }), - files.read().err.as_ref().map(|err| { - rsx! ( - div { - code { "{err}" } - button { onclick: move |_| files.write().clear_err(), "x" } - } - ) - }) + ) + }), + files.read().err.as_ref().map(|err| { + rsx! ( + div { + code { "{err}" } + button { onclick: move |_| files.write().clear_err(), "x" } + } + ) + }) + } } - }) + } } struct Files { diff --git a/examples/svg.rs b/examples/svg.rs index 8e993b3e3..b331e7a6a 100644 --- a/examples/svg.rs +++ b/examples/svg.rs @@ -9,7 +9,7 @@ fn main() { fn app(cx: Scope) -> Element { let val = use_state(&cx, || 5); - cx.render(rsx! { + render! { div { user_select: "none", webkit_user_select: "none", @@ -31,7 +31,7 @@ fn app(cx: Scope) -> Element { } } } - }) + } } #[derive(Props)] @@ -78,7 +78,7 @@ pub fn Die<'a>(cx: Scope<'a, DieProps<'a>>) -> Element { }) }); - rsx!(cx, + render! { svg { onclick: move |e| cx.props.onclick.call(e), prevent_default: "onclick", @@ -97,5 +97,5 @@ pub fn Die<'a>(cx: Scope<'a, DieProps<'a>>) -> Element { dots } - ) + } } diff --git a/notes/README.md b/notes/README.md index 21d6d7329..a182191ae 100644 --- a/notes/README.md +++ b/notes/README.md @@ -101,7 +101,7 @@ fn example(cx: Scope) -> Element { // both of these are equivalent cx.render(rsx!("hello world")) - rsx!(cx, "hello world!") + render!("hello world!") } ``` @@ -235,7 +235,7 @@ use hooks to define state and modify it from within listeners. fn app(cx: Scope) -> Element { let name = use_state(&cx, || "world"); - rsx!(cx, "hello {name}!") + render!("hello {name}!") } ``` diff --git a/packages/core-macro/src/lib.rs b/packages/core-macro/src/lib.rs index 4247c17d9..43ad7015a 100644 --- a/packages/core-macro/src/lib.rs +++ b/packages/core-macro/src/lib.rs @@ -72,6 +72,26 @@ pub fn rsx(s: TokenStream) -> TokenStream { } } +/// The render! macro makes it easy for developers to write jsx-style markup in their components. +/// +/// The render macro automatically renders rsx - making it unhygenic. +/// +/// ## Complete Reference Guide: +/// ```ignore +#[doc = include_str!("../../../examples/rsx_usage.rs")] +/// ``` +#[proc_macro] +pub fn render(s: TokenStream) -> TokenStream { + match syn::parse::(s) { + Err(err) => err.to_compile_error().into(), + Ok(body) => quote::quote! { + cx.render(#body) + } + .into_token_stream() + .into(), + } +} + /// Derive props for a component within the component definition. /// /// This macro provides a simple transformation from `Scope<{}>` to `Scope

`, diff --git a/packages/core/README.md b/packages/core/README.md index 0cb185f45..9b0b14fff 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -7,7 +7,7 @@ To build new apps with Dioxus or to extend the ecosystem with new hooks or compo ```rust, ignore fn app(cx: Scope) -> Element { - rsx!(cx, div { "hello world" }) + render!(div { "hello world" }) } fn main() { diff --git a/packages/core/src/events.rs b/packages/core/src/events.rs index c1347ef33..0668f7582 100644 --- a/packages/core/src/events.rs +++ b/packages/core/src/events.rs @@ -32,7 +32,7 @@ impl BubbleState { /// # Example /// ```rust, ignore /// fn App(cx: Scope) -> Element { -/// rsx!(cx, div { +/// render!(div { /// onclick: move |_| println!("Clicked!") /// }) /// } diff --git a/packages/core/src/scopes.rs b/packages/core/src/scopes.rs index 582785003..2e7604d9f 100644 --- a/packages/core/src/scopes.rs +++ b/packages/core/src/scopes.rs @@ -528,7 +528,7 @@ impl ScopeState { /// /// ```rust, ignore /// fn App(cx: Scope) -> Element { - /// rsx!(cx, div { "Subtree {id}"}) + /// render!(div { "Subtree {id}"}) /// }; /// ``` /// @@ -659,12 +659,12 @@ impl ScopeState { /// /// static App: Component = |cx| { /// cx.use_hook(|| cx.provide_context(SharedState("world"))); - /// rsx!(cx, Child {}) + /// render!(Child {}) /// } /// /// static Child: Component = |cx| { /// let state = cx.consume_state::(); - /// rsx!(cx, div { "hello {state.0}" }) + /// render!(div { "hello {state.0}" }) /// } /// ``` pub fn provide_context(&self, value: T) -> T { @@ -685,12 +685,12 @@ impl ScopeState { /// /// static App: Component = |cx| { /// cx.use_hook(|| cx.provide_root_context(SharedState("world"))); - /// rsx!(cx, Child {}) + /// render!(Child {}) /// } /// /// static Child: Component = |cx| { /// let state = cx.consume_state::(); - /// rsx!(cx, div { "hello {state.0}" }) + /// render!(div { "hello {state.0}" }) /// } /// ``` pub fn provide_root_context(&self, value: T) -> T { diff --git a/packages/core/src/virtual_dom.rs b/packages/core/src/virtual_dom.rs index 15006a9d7..794eaa3f6 100644 --- a/packages/core/src/virtual_dom.rs +++ b/packages/core/src/virtual_dom.rs @@ -597,7 +597,7 @@ impl VirtualDom { /// /// ```rust, ignore /// fn Base(cx: Scope) -> Element { - /// rsx!(cx, div {}) + /// render!(div {}) /// } /// /// let dom = VirtualDom::new(Base); @@ -617,7 +617,7 @@ impl VirtualDom { /// /// ```rust, ignore /// fn Base(cx: Scope) -> Element { - /// rsx!(cx, div {}) + /// render!(div {}) /// } /// /// let dom = VirtualDom::new(Base); @@ -639,7 +639,7 @@ impl VirtualDom { /// /// ```rust, ignore /// fn Base(cx: Scope) -> Element { - /// rsx!(cx, div {}) + /// render!(div {}) /// } /// /// let dom = VirtualDom::new(Base); @@ -662,7 +662,7 @@ impl VirtualDom { /// /// ```rust, ignore /// fn Base(cx: Scope) -> Element { - /// rsx!(cx, div {}) + /// render!(div {}) /// } /// /// let dom = VirtualDom::new(Base); diff --git a/packages/dioxus/benches/jsframework.rs b/packages/dioxus/benches/jsframework.rs index c0fbf4764..3a7198012 100644 --- a/packages/dioxus/benches/jsframework.rs +++ b/packages/dioxus/benches/jsframework.rs @@ -23,7 +23,7 @@ fn create_rows(c: &mut Criterion) { static App: Component = |cx| { let mut rng = SmallRng::from_entropy(); - rsx!(cx, table { + render!(table { tbody { (0..10_000_usize).map(|f| { let label = Label::new(&mut rng); diff --git a/packages/dioxus/src/lib.rs b/packages/dioxus/src/lib.rs index 43462ab52..a8312aa52 100644 --- a/packages/dioxus/src/lib.rs +++ b/packages/dioxus/src/lib.rs @@ -26,7 +26,7 @@ pub mod prelude { pub use dioxus_core::prelude::*; #[cfg(feature = "macro")] - pub use dioxus_core_macro::{format_args_f, inline_props, rsx, Props}; + pub use dioxus_core_macro::{format_args_f, inline_props, render, rsx, Props}; #[cfg(feature = "html")] pub use dioxus_html as dioxus_elements; diff --git a/packages/dioxus/tests/diffing.rs b/packages/dioxus/tests/diffing.rs index 21a9d4f38..f01c0e6c3 100644 --- a/packages/dioxus/tests/diffing.rs +++ b/packages/dioxus/tests/diffing.rs @@ -9,7 +9,7 @@ use dioxus::prelude::*; fn new_dom() -> VirtualDom { - VirtualDom::new(|cx| rsx!(cx, "hi")) + VirtualDom::new(|cx| render!("hi")) } use dioxus_core::DomEdit::*; diff --git a/packages/dioxus/tests/earlyabort.rs b/packages/dioxus/tests/earlyabort.rs index e996b3d4c..037240cb6 100644 --- a/packages/dioxus/tests/earlyabort.rs +++ b/packages/dioxus/tests/earlyabort.rs @@ -28,7 +28,7 @@ fn test_early_abort() { return None; } - rsx!(cx, div { "Hello, world!" }) + render!(div { "Hello, world!" }) }; let mut dom = new_dom(app, ()); diff --git a/packages/dioxus/tests/miri_stress.rs b/packages/dioxus/tests/miri_stress.rs index 6502c1a56..a5f90907c 100644 --- a/packages/dioxus/tests/miri_stress.rs +++ b/packages/dioxus/tests/miri_stress.rs @@ -54,7 +54,7 @@ fn test_memory_leak() { } fn BorrowedChild<'a>(cx: Scope<'a, BorrowedProps<'a>>) -> Element { - rsx!(cx, div { + render!(div { "goodbye {cx.props.na}" Child {} Child {} @@ -62,7 +62,7 @@ fn test_memory_leak() { } fn Child(cx: Scope) -> Element { - rsx!(cx, div { "goodbye world" }) + render!(div { "goodbye world" }) } let mut dom = new_dom(app, ()); @@ -101,7 +101,7 @@ fn memo_works_properly() { } fn Child(cx: Scope) -> Element { - rsx!(cx, div { "goodbye world" }) + render!(div { "goodbye world" }) } let mut dom = new_dom(app, ()); @@ -133,7 +133,7 @@ fn free_works_on_root_props() { } fn Child(cx: Scope) -> Element { - rsx!(cx, "child {cx.props.a}") + render!("child {cx.props.a}") } struct Custom { @@ -165,7 +165,7 @@ fn free_works_on_borrowed() { fn Child<'a>(cx: Scope<'a, ChildProps<'a>>) -> Element { dbg!("rendering child"); - rsx!(cx, "child {cx.props.a}, {cx.props.b}") + render!("child {cx.props.a}, {cx.props.b}") } impl Drop for ChildProps<'_> { @@ -193,7 +193,7 @@ fn free_works_on_root_hooks() { fn app(cx: Scope) -> Element { let name = cx.use_hook(|| Droppable(String::from("asd"))); - rsx!(cx, div { "{name.0}" }) + render!(div { "{name.0}" }) } let mut dom = new_dom(app, ()); @@ -208,9 +208,9 @@ fn old_props_arent_stale() { *cnt += 1; if *cnt == 1 { - rsx!(cx, div { Child { a: "abcdef".to_string() } }) + render!(div { Child { a: "abcdef".to_string() } }) } else { - rsx!(cx, div { Child { a: "abcdef".to_string() } }) + render!(div { Child { a: "abcdef".to_string() } }) } } @@ -220,7 +220,7 @@ fn old_props_arent_stale() { } fn Child(cx: Scope) -> Element { dbg!("rendering child", &cx.props.a); - rsx!(cx, div { "child {cx.props.a}" }) + render!(div { "child {cx.props.a}" }) } let mut dom = new_dom(app, ()); @@ -250,7 +250,7 @@ fn old_props_arent_stale() { #[test] fn basic() { fn app(cx: Scope) -> Element { - rsx!(cx, div { + render!(div { Child { a: "abcdef".to_string() } }) } @@ -262,7 +262,7 @@ fn basic() { fn Child(cx: Scope) -> Element { dbg!("rendering child", &cx.props.a); - rsx!(cx, div { "child {cx.props.a}" }) + render!(div { "child {cx.props.a}" }) } let mut dom = new_dom(app, ()); @@ -290,7 +290,7 @@ fn leak_thru_children() { #[inline_props] fn Child(cx: Scope, name: String) -> Element { - rsx!(cx, div { "child {name}" }) + render!(div { "child {name}" }) } let mut dom = new_dom(app, ()); @@ -315,8 +315,7 @@ fn test_pass_thru() { } fn NavMenu(cx: Scope) -> Element { - rsx!(cx, - NavBrand {} + render!( NavBrand {} div { NavStart {} NavEnd {} @@ -325,15 +324,15 @@ fn test_pass_thru() { } fn NavBrand(cx: Scope) -> Element { - rsx!(cx, div {}) + render!(div {}) } fn NavStart(cx: Scope) -> Element { - rsx!(cx, div {}) + render!(div {}) } fn NavEnd(cx: Scope) -> Element { - rsx!(cx, div {}) + render!(div {}) } #[inline_props] diff --git a/packages/dioxus/tests/passthru.rs b/packages/dioxus/tests/passthru.rs index 730a6b93e..87d9f8545 100644 --- a/packages/dioxus/tests/passthru.rs +++ b/packages/dioxus/tests/passthru.rs @@ -10,7 +10,7 @@ use dioxus::prelude::*; fn new_dom() -> VirtualDom { - VirtualDom::new(|cx| rsx!(cx, "hi")) + VirtualDom::new(|cx| render!("hi")) } use dioxus_core::DomEdit::*; diff --git a/packages/dioxus/tests/vdom_rebuild.rs b/packages/dioxus/tests/vdom_rebuild.rs index 63a57fc33..9ddf03d18 100644 --- a/packages/dioxus/tests/vdom_rebuild.rs +++ b/packages/dioxus/tests/vdom_rebuild.rs @@ -15,7 +15,7 @@ use dioxus_core::DomEdit::*; #[test] fn app_runs() { - static App: Component = |cx| rsx!(cx, div{"hello"} ); + static App: Component = |cx| render!(div{"hello"} ); let mut vdom = VirtualDom::new(App); let edits = vdom.rebuild(); diff --git a/packages/native-core-macro/tests/called_minimally_on_build.rs b/packages/native-core-macro/tests/called_minimally_on_build.rs index 390bfc7bc..f6bca5639 100644 --- a/packages/native-core-macro/tests/called_minimally_on_build.rs +++ b/packages/native-core-macro/tests/called_minimally_on_build.rs @@ -67,7 +67,7 @@ macro_rules! test_state{ fn state_reduce_initally_called_minimally() { #[allow(non_snake_case)] fn Base(cx: Scope) -> Element { - rsx!(cx, div { + render!(div { div{ div{ p{} diff --git a/packages/native-core-macro/tests/change_nodes.rs b/packages/native-core-macro/tests/change_nodes.rs index 56d31709b..9c712fcb2 100644 --- a/packages/native-core-macro/tests/change_nodes.rs +++ b/packages/native-core-macro/tests/change_nodes.rs @@ -13,7 +13,7 @@ struct Empty {} fn remove_node() { #[allow(non_snake_case)] fn Base(cx: Scope) -> Element { - rsx!(cx, div {}) + render!(div {}) } let vdom = VirtualDom::new(Base); @@ -87,7 +87,7 @@ fn remove_node() { fn add_node() { #[allow(non_snake_case)] fn Base(cx: Scope) -> Element { - rsx!(cx, div {}) + render!(div {}) } let vdom = VirtualDom::new(Base); diff --git a/packages/native-core-macro/tests/initial_build.rs b/packages/native-core-macro/tests/initial_build.rs index 485ce81f0..190dad647 100644 --- a/packages/native-core-macro/tests/initial_build.rs +++ b/packages/native-core-macro/tests/initial_build.rs @@ -16,7 +16,7 @@ fn initial_build_simple() { #[allow(non_snake_case)] fn Base(cx: Scope) -> Element { - rsx!(cx, div {}) + render!(div {}) } let vdom = VirtualDom::new(Base); @@ -47,7 +47,7 @@ fn initial_build_simple() { fn initial_build_with_children() { #[allow(non_snake_case)] fn Base(cx: Scope) -> Element { - rsx!(cx, div {}) + render!(div {}) } let vdom = VirtualDom::new(Base); diff --git a/packages/native-core-macro/tests/peristant_iterator.rs b/packages/native-core-macro/tests/peristant_iterator.rs index 65b16706a..f67874724 100644 --- a/packages/native-core-macro/tests/peristant_iterator.rs +++ b/packages/native-core-macro/tests/peristant_iterator.rs @@ -15,7 +15,7 @@ struct Empty {} fn traverse() { #[allow(non_snake_case)] fn Base(cx: Scope) -> Element { - rsx!(cx, div {}) + render!(div {}) } let vdom = VirtualDom::new(Base); let mutations = vdom.create_vnodes(rsx! { @@ -108,7 +108,7 @@ fn traverse() { fn persist_removes() { #[allow(non_snake_case)] fn Base(cx: Scope) -> Element { - rsx!(cx, div {}) + render!(div {}) } let vdom = VirtualDom::new(Base); let (build, update) = vdom.diff_lazynodes( @@ -196,7 +196,7 @@ fn persist_removes() { fn persist_instertions_before() { #[allow(non_snake_case)] fn Base(cx: Scope) -> Element { - rsx!(cx, div {}) + render!(div {}) } let vdom = VirtualDom::new(Base); let (build, update) = vdom.diff_lazynodes( @@ -262,7 +262,7 @@ fn persist_instertions_before() { fn persist_instertions_after() { #[allow(non_snake_case)] fn Base(cx: Scope) -> Element { - rsx!(cx, div {}) + render!(div {}) } let vdom = VirtualDom::new(Base); let (build, update) = vdom.diff_lazynodes( diff --git a/packages/native-core-macro/tests/update_state.rs b/packages/native-core-macro/tests/update_state.rs index 25e4dec47..2725120d6 100644 --- a/packages/native-core-macro/tests/update_state.rs +++ b/packages/native-core-macro/tests/update_state.rs @@ -163,7 +163,7 @@ struct StateTester { fn state_initial() { #[allow(non_snake_case)] fn Base(cx: Scope) -> Element { - rsx!(cx, div { + render!(div { p{} h1{} }) @@ -240,7 +240,7 @@ fn state_initial() { fn state_reduce_parent_called_minimally_on_update() { #[allow(non_snake_case)] fn Base(cx: Scope) -> Element { - rsx!(cx, div { + render!(div { width: "100%", div{ div{ @@ -307,7 +307,7 @@ fn state_reduce_parent_called_minimally_on_update() { fn state_reduce_child_called_minimally_on_update() { #[allow(non_snake_case)] fn Base(cx: Scope) -> Element { - rsx!(cx, div { + render!(div { div{ div{ p{ @@ -435,7 +435,7 @@ impl NodeDepState<()> for CDepCallCounter { fn dependancies_order_independant() { #[allow(non_snake_case)] fn Base(cx: Scope) -> Element { - rsx!(cx, div { + render!(div { width: "100%", p{ "hello" diff --git a/packages/rsx/src/lib.rs b/packages/rsx/src/lib.rs index a5b8143f2..3cd649037 100644 --- a/packages/rsx/src/lib.rs +++ b/packages/rsx/src/lib.rs @@ -30,25 +30,15 @@ use proc_macro2::TokenStream as TokenStream2; use quote::{quote, ToTokens, TokenStreamExt}; use syn::{ parse::{Parse, ParseStream}, - Ident, Result, Token, + Result, Token, }; pub struct CallBody { - pub custom_context: Option, pub roots: Vec, } impl Parse for CallBody { fn parse(input: ParseStream) -> Result { - let custom_context = if input.peek(Ident) && input.peek2(Token![,]) { - let name = input.parse::()?; - input.parse::()?; - - Some(name) - } else { - None - }; - let mut roots = Vec::new(); while !input.is_empty() { @@ -61,10 +51,7 @@ impl Parse for CallBody { roots.push(node); } - Ok(Self { - custom_context, - roots, - }) + Ok(Self { roots }) } } @@ -79,22 +66,12 @@ impl ToTokens for CallBody { quote! { __cx.fragment_root([ #(#childs),* ]) } }; - match &self.custom_context { - // The `in cx` pattern allows directly rendering - Some(ident) => out_tokens.append_all(quote! { - #ident.render(LazyNodes::new(move |__cx: NodeFactory| -> VNode { - use dioxus_elements::{GlobalAttributes, SvgAttributes}; - #inner - })) - }), - - // Otherwise we just build the LazyNode wrapper - None => out_tokens.append_all(quote! { - LazyNodes::new(move |__cx: NodeFactory| -> VNode { - use dioxus_elements::{GlobalAttributes, SvgAttributes}; - #inner - }) - }), - }; + // Otherwise we just build the LazyNode wrapper + out_tokens.append_all(quote! { + LazyNodes::new(move |__cx: NodeFactory| -> VNode { + use dioxus_elements::{GlobalAttributes, SvgAttributes}; + #inner + }) + }) } } diff --git a/packages/rsx_interpreter/src/captuered_context.rs b/packages/rsx_interpreter/src/captuered_context.rs index af205749b..df8a8dde4 100644 --- a/packages/rsx_interpreter/src/captuered_context.rs +++ b/packages/rsx_interpreter/src/captuered_context.rs @@ -30,10 +30,7 @@ impl CapturedContextBuilder { } pub fn from_call_body(body: CallBody) -> Result { - let mut new = Self { - custom_context: body.custom_context, - ..Default::default() - }; + let mut new = Self::default(); for node in body.roots { new.extend(Self::find_captured(node)?); } diff --git a/packages/rsx_interpreter/tests/render.rs b/packages/rsx_interpreter/tests/render.rs index 7553ec179..69ff66466 100644 --- a/packages/rsx_interpreter/tests/render.rs +++ b/packages/rsx_interpreter/tests/render.rs @@ -4,7 +4,7 @@ use dioxus::prelude::*; #[allow(non_snake_case)] fn render_basic() { fn Base(cx: Scope) -> Element { - rsx!(cx, div {}) + render!(div {}) } let dom = VirtualDom::new(Base); @@ -44,7 +44,7 @@ fn render_basic() { #[allow(non_snake_case)] fn render_nested() { fn Base(cx: Scope) -> Element { - rsx!(cx, div {}) + render!(div {}) } let dom = VirtualDom::new(Base); @@ -96,7 +96,7 @@ fn render_nested() { #[allow(non_snake_case)] fn render_custom_attribute() { fn Base(cx: Scope) -> Element { - rsx!(cx, div {}) + render!(div {}) } let dom = VirtualDom::new(Base); @@ -144,11 +144,11 @@ fn render_custom_attribute() { #[allow(non_snake_case)] fn render_component() { fn Comp(cx: Scope) -> Element { - rsx!(cx, div {}) + render!(div {}) } fn Base(cx: Scope) -> Element { - rsx!(cx, div {}) + render!(div {}) } let dom = VirtualDom::new(Base); @@ -200,7 +200,7 @@ fn render_component() { #[allow(non_snake_case)] fn render_iterator() { fn Base(cx: Scope) -> Element { - rsx!(cx, div {}) + render!(div {}) } let dom = VirtualDom::new(Base); @@ -254,7 +254,7 @@ fn render_iterator() { #[allow(non_snake_case)] fn render_captured_variable() { fn Base(cx: Scope) -> Element { - rsx!(cx, div {}) + render!(div {}) } let dom = VirtualDom::new(Base); @@ -309,7 +309,7 @@ fn render_captured_variable() { #[allow(non_snake_case)] fn render_listener() { fn Base(cx: Scope) -> Element { - rsx!(cx, div {}) + render!(div {}) } let dom = VirtualDom::new(Base); diff --git a/packages/web/src/lib.rs b/packages/web/src/lib.rs index 81e76afbc..97ae2e54b 100644 --- a/packages/web/src/lib.rs +++ b/packages/web/src/lib.rs @@ -89,7 +89,7 @@ mod util; /// } /// /// static App: Component = |cx| { -/// rsx!(cx, div {"hello world"}) +/// render!(div {"hello world"}) /// } /// ``` pub fn launch(root_component: Component) { @@ -140,7 +140,7 @@ pub fn launch_cfg(root: Component, config: Config) { /// } /// /// static App: Component = |cx| { -/// rsx!(cx, div {"hello {cx.props.name}"}) +/// render!(div {"hello {cx.props.name}"}) /// } /// ``` pub fn launch_with_props(root_component: Component, root_properties: T, config: Config)