Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to clone model fields in view! macro #576

Open
hwittenborn opened this issue Nov 21, 2023 · 6 comments
Open

Unable to clone model fields in view! macro #576

hwittenborn opened this issue Nov 21, 2023 · 6 comments

Comments

@hwittenborn
Copy link
Member

hwittenborn commented Nov 21, 2023

I'm trying to do something similar to this inside a view! macro in my codebase:

connect_changed[model.errors as errors, sender] => move |name_input| { ...

This is currently failing to compile though:

error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
   --> src/login.rs:321:46
    |
321 |                         connect_changed[model.errors as errors, sender] => move |name_input| {
    |                                              ^ expected one of `:`, `;`, `=`, `@`, or `|`

I'm assuming this should be allowed since glib::clone! allows for it (see https://gtk-rs.org/gtk-rs-core/stable/latest/docs/glib/macro.clone.html#errors). I'm not sure how easy this would be to add support for in the parser though, but it would make my code significantly cleaner if I was able to.

@hwittenborn
Copy link
Member Author

It looks like this is already handled as mentioned in #162 (comment), but it doesn't look like such behavior is currently documented.

Does the documentation for that not exist, or am I just looking in the wrong place?

@hwittenborn
Copy link
Member Author

I looked here in the documentation as well, and it also doesn't appear such behavior is documented.

@hwittenborn
Copy link
Member Author

Something I found a bit surprising is that using the new_var = old_var.field syntax doesn't automatically clone the field:

// Automatically clones `sender`
connect_changed[sender] => move |name_input| { ...

// Doesn't clone `model.errors`
connect_changed[errors = model.errors, sender] => move |name_input| { ...

// Clone's `model.errors` through manual `.clone()` call
connect_changed[errors = model.errors.clone(), sender] => move |name_input| { ...

Since the [var_name] syntax automatically clones the variable, I was thinking that the [new_var = old_var.field] syntax would also.

I can't really think of a case where you'd just rename with the [...] block but not clone, because at that point you could just let the closure take ownership of the old_var in question. Is this intended behavior for some other reason?

@AaronErhardt
Copy link
Member

Something I found a bit surprising is that using the new_var = old_var.field syntax doesn't automatically clone the field:

This is because you might not want to use .clone() to duplicate your data. It's surely the most common trait, but some types in Rust have use methods.

@hwittenborn
Copy link
Member Author

I was mostly wondering when you wouldn't want to though, as I was thinking you'd pretty much always want to clone when using stuff like [errors = model.errors]. I guess if you had something like model.errors.error1, then it might make sense to just pass in the entire model.errors struct into the closure, while leaving the rest of model outside of it.

That makes enough sense to me, but the currently behavior for the [var = var.field] stuff still needs documented, right?

@AaronErhardt
Copy link
Member

Yes, documentation is missing and we could add a shorter syntax for cloning struct fields, so we can keep this issue open until this is resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants