From f2c1c05792cc365058b2cbf038b420d140b1d62f Mon Sep 17 00:00:00 2001 From: traxys Date: Mon, 3 Jul 2023 15:13:35 +0200 Subject: [PATCH] Add a helper macro for properties & async The to_owned macro is helpful to handle hooks with async components, but when using properties it can be problematic because `cx` will be moved in the async block, and will result in a compilation error. This adds a new helper that allows to make either hooks or properties owned. --- packages/hooks/src/lib.rs | 41 +++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/packages/hooks/src/lib.rs b/packages/hooks/src/lib.rs index 1e718eda3..21795a9d6 100644 --- a/packages/hooks/src/lib.rs +++ b/packages/hooks/src/lib.rs @@ -1,24 +1,53 @@ #[macro_export] -/// A helper macro for using hooks in async environements. +/// A helper macro for using hooks and properties in async environements. /// /// # Usage /// /// -/// ```ignore +/// ``` +/// # use dioxus::prelude::*; +/// # +/// # #[derive(Props, PartialEq)] +/// # struct Props { +/// # prop: String, +/// # } +/// # fn Component(cx: Scope) -> Element { +/// /// let (data) = use_ref(cx, || {}); /// /// let handle_thing = move |_| { -/// to_owned![data] +/// to_owned![data, cx.props.prop]; /// cx.spawn(async move { /// // do stuff /// }); -/// } +/// }; +/// # handle_thing(()); +/// # None } /// ``` macro_rules! to_owned { - ($($es:ident),+) => {$( + // Rule matching simple symbols without a path + ($es:ident $(, $($rest:tt)*)?) => { #[allow(unused_mut)] let mut $es = $es.to_owned(); - )*} + $( to_owned![$($rest)*] )? + }; + + // We need to find the last element in a path, for this we need to unstack the path part by + // part using, separating what we have with a '@' + ($($deref:ident).* $(, $($rest:tt)*)?) => { + to_owned![@ $($deref).* $(, $($rest)*)?] + }; + + // Take the head of the path and add it to the list of $deref + ($($deref:ident)* @ $head:ident $( . $tail:ident)+ $(, $($rest:tt)*)?) => { + to_owned![$($deref)* $head @ $($tail).+ $(, $($rest)*)?] + }; + // We have exhausted the path, use the last as a name + ($($deref:ident)* @ $last:ident $(, $($rest:tt)*)? ) => { + #[allow(unused_mut)] + let mut $last = $($deref .)* $last .to_owned(); + $(to_owned![$($rest)*])? + }; } mod usecontext;