Fix issue with mutability in component macro
This commit is contained in:
5 files changed
+47
-22
No files matched your search
@@ -17,7 +17,12 @@ fn app() -> Element {
|
|||||||
if running() {
|
if running() {
|
||||||
count += 1;
|
count += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let val = running.read();
|
||||||
|
|
||||||
tokio::time::sleep(Duration::from_millis(400)).await;
|
tokio::time::sleep(Duration::from_millis(400)).await;
|
||||||
|
|
||||||
|
println!("Running: {}", *val);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+4
-8
@@ -80,8 +80,7 @@ pub fn app() -> Element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn TodoHeader(todos: Signal<HashMap<u32, TodoItem>>) -> Element {
|
pub fn TodoHeader(mut todos: Signal<HashMap<u32, TodoItem>>) -> Element {
|
||||||
let mut todos = todos;
|
|
||||||
let mut draft = use_signal(|| "".to_string());
|
let mut draft = use_signal(|| "".to_string());
|
||||||
let mut todo_id = use_signal(|| 0);
|
let mut todo_id = use_signal(|| 0);
|
||||||
|
|
||||||
@@ -115,8 +114,7 @@ pub fn TodoHeader(todos: Signal<HashMap<u32, TodoItem>>) -> Element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn TodoEntry(todos: Signal<HashMap<u32, TodoItem>>, id: u32) -> Element {
|
pub fn TodoEntry(mut todos: Signal<HashMap<u32, TodoItem>>, id: u32) -> Element {
|
||||||
let mut todos = todos;
|
|
||||||
let mut is_editing = use_signal(|| false);
|
let mut is_editing = use_signal(|| false);
|
||||||
let checked = use_selector(move || todos.read().get(&id).unwrap().checked);
|
let checked = use_selector(move || todos.read().get(&id).unwrap().checked);
|
||||||
let contents = use_selector(move || todos.read().get(&id).unwrap().contents.clone());
|
let contents = use_selector(move || todos.read().get(&id).unwrap().contents.clone());
|
||||||
@@ -164,12 +162,10 @@ pub fn TodoEntry(todos: Signal<HashMap<u32, TodoItem>>, id: u32) -> Element {
|
|||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn ListFooter(
|
pub fn ListFooter(
|
||||||
todos: Signal<HashMap<u32, TodoItem>>,
|
mut todos: Signal<HashMap<u32, TodoItem>>,
|
||||||
active_todo_count: ReadOnlySignal<usize>,
|
active_todo_count: ReadOnlySignal<usize>,
|
||||||
filter: Signal<FilterState>,
|
mut filter: Signal<FilterState>,
|
||||||
) -> Element {
|
) -> Element {
|
||||||
let mut todos = todos;
|
|
||||||
let mut filter = filter;
|
|
||||||
let show_clear_completed = use_selector(move || todos.read().values().any(|todo| todo.checked));
|
let show_clear_completed = use_selector(move || todos.read().values().any(|todo| todo.checked));
|
||||||
|
|
||||||
rsx! {
|
rsx! {
|
||||||
|
|||||||
@@ -46,12 +46,20 @@ fn get_props_struct(component_body: &ComponentBody) -> ItemStruct {
|
|||||||
..
|
..
|
||||||
} = sig;
|
} = sig;
|
||||||
|
|
||||||
// Skip first arg since that's the context
|
|
||||||
let struct_fields = inputs.iter().map(move |f| {
|
let struct_fields = inputs.iter().map(move |f| {
|
||||||
match f {
|
match f {
|
||||||
FnArg::Receiver(_) => unreachable!(), // Unreachable because of ComponentBody parsing
|
FnArg::Receiver(_) => unreachable!(), // Unreachable because of ComponentBody parsing
|
||||||
FnArg::Typed(pt) => {
|
FnArg::Typed(pt) => {
|
||||||
let arg_pat = &pt.pat; // Pattern (identifier)
|
let arg_pat = match pt.pat.as_ref() {
|
||||||
|
// rip off mutability
|
||||||
|
Pat::Ident(f) => {
|
||||||
|
let mut f = f.clone();
|
||||||
|
f.mutability = None;
|
||||||
|
quote! { #f }
|
||||||
|
}
|
||||||
|
a => quote! { #a },
|
||||||
|
};
|
||||||
|
|
||||||
let arg_colon = &pt.colon_token;
|
let arg_colon = &pt.colon_token;
|
||||||
let arg_ty = &pt.ty; // Type
|
let arg_ty = &pt.ty; // Type
|
||||||
let arg_attrs = &pt.attrs; // Attributes
|
let arg_attrs = &pt.attrs; // Attributes
|
||||||
@@ -247,7 +255,21 @@ fn get_function(component_body: &ComponentBody) -> ItemFn {
|
|||||||
// Skip first arg since that's the context
|
// Skip first arg since that's the context
|
||||||
let struct_field_names = inputs.iter().filter_map(|f| match f {
|
let struct_field_names = inputs.iter().filter_map(|f| match f {
|
||||||
FnArg::Receiver(_) => unreachable!(), // ComponentBody prohibits receiver parameters.
|
FnArg::Receiver(_) => unreachable!(), // ComponentBody prohibits receiver parameters.
|
||||||
FnArg::Typed(pt) => Some(&pt.pat),
|
FnArg::Typed(pt) => {
|
||||||
|
let pat = &pt.pat;
|
||||||
|
|
||||||
|
let mut pat = pat.clone();
|
||||||
|
|
||||||
|
// rip off mutability, but still write it out eventually
|
||||||
|
match pat.as_mut() {
|
||||||
|
Pat::Ident(ref mut pat_ident) => {
|
||||||
|
pat_ident.mutability = None;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(quote!(mut #pat))
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let first_lifetime = if let Some(GenericParam::Lifetime(lt)) = generics.params.first() {
|
let first_lifetime = if let Some(GenericParam::Lifetime(lt)) = generics.params.first() {
|
||||||
@@ -293,7 +315,7 @@ fn get_function(component_body: &ComponentBody) -> ItemFn {
|
|||||||
parse_quote! {
|
parse_quote! {
|
||||||
#(#fn_attrs)*
|
#(#fn_attrs)*
|
||||||
#(#props_docs)*
|
#(#props_docs)*
|
||||||
#asyncness #vis fn #fn_ident #fn_generics (__props: #struct_ident #generics_no_bounds) #fn_output
|
#asyncness #vis fn #fn_ident #fn_generics (mut __props: #struct_ident #generics_no_bounds) #fn_output
|
||||||
#where_clause
|
#where_clause
|
||||||
{
|
{
|
||||||
let #struct_ident { #(#struct_field_names),* } = __props;
|
let #struct_ident { #(#struct_field_names),* } = __props;
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ pub struct HistoryButtonProps {
|
|||||||
#[component]
|
#[component]
|
||||||
pub fn GoBackButton(
|
pub fn GoBackButton(
|
||||||
/// The props...
|
/// The props...
|
||||||
props: HistoryButtonProps,
|
mut props: HistoryButtonProps,
|
||||||
) -> Element {
|
) -> Element {
|
||||||
let HistoryButtonProps { children } = props;
|
let HistoryButtonProps { children } = props;
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ pub fn GoBackButton(
|
|||||||
#[component]
|
#[component]
|
||||||
pub fn GoForwardButton(
|
pub fn GoForwardButton(
|
||||||
/// Props...
|
/// Props...
|
||||||
props: HistoryButtonProps,
|
mut props: HistoryButtonProps,
|
||||||
) -> Element {
|
) -> Element {
|
||||||
let HistoryButtonProps { children } = props;
|
let HistoryButtonProps { children } = props;
|
||||||
|
|
||||||
|
|||||||
@@ -245,7 +245,17 @@ impl<T: 'static> Signal<T> {
|
|||||||
GenerationalRef::map(inner, |v| &v.value)
|
GenerationalRef::map(inner, |v| &v.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get a mutable reference to the signal's value.
|
||||||
|
///
|
||||||
|
/// If the signal has been dropped, this will panic.
|
||||||
|
#[track_caller]
|
||||||
|
pub fn write<'a>(&'a mut self) -> Write<'a, T> {
|
||||||
|
self.write_unchecked()
|
||||||
|
}
|
||||||
|
|
||||||
/// Write to the value through an immutable reference.
|
/// Write to the value through an immutable reference.
|
||||||
|
///
|
||||||
|
/// This is public since it's useful in many scenarios, but we generally recommend mutation through [`Self::write`] instead.
|
||||||
pub fn write_unchecked(&self) -> Write<T> {
|
pub fn write_unchecked(&self) -> Write<T> {
|
||||||
let inner = self.inner.write();
|
let inner = self.inner.write();
|
||||||
let borrow = GenerationalRefMut::map(inner, |v| &mut v.value);
|
let borrow = GenerationalRefMut::map(inner, |v| &mut v.value);
|
||||||
@@ -255,14 +265,6 @@ impl<T: 'static> Signal<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a mutable reference to the signal's value.
|
|
||||||
///
|
|
||||||
/// If the signal has been dropped, this will panic.
|
|
||||||
#[track_caller]
|
|
||||||
pub fn write<'a>(&'a mut self) -> Write<'a, T> {
|
|
||||||
self.write_unchecked()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn update_subscribers(&self) {
|
fn update_subscribers(&self) {
|
||||||
{
|
{
|
||||||
let inner = self.inner.read();
|
let inner = self.inner.read();
|
||||||
|
|||||||
Reference in new issue
Block a user