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

confused by moved_ownership example #348

Open
timglabisch opened this issue Jun 19, 2016 · 5 comments
Open

confused by moved_ownership example #348

timglabisch opened this issue Jun 19, 2016 · 5 comments

Comments

@timglabisch
Copy link

Hello,

i hope it's fine that i opened this issue - it's more or less a question, not a real issue.

i am trying to pass (cone) a struct what owns a String from my main function to a handler,
more or less the same like:

https://github.com/nickel-org/nickel.rs/blob/master/examples/moved_ownership.rs

for rust / nickel beginners it's really hard so understand the limitations of the middleware! macro.

could you add some more complex examples (structs / mutable / ...) about this topic?

@Ryman
Copy link
Member

Ryman commented Jun 23, 2016

I don't mind expanding the example if it would help to clarify for others, can you give me an example of the error you're coming up against? The intent of the example is to give people an understanding of why they are possibly encountering ownership issues (which isn't really a limitation of the macro per se).

@andrewjensen
Copy link

Sorry to wake up an old thread, but I just ran into this issue as well. I had some central config for my app, loaded from a .env file, and I wanted to pass an api_key around to a couple of endpoints which in turn called a third-party service. I was getting errors related to moving config as I referenced &config.api_key in the endpoints.

I realized that I couldn't just do what the example shows, because my app has multiple endpoints, like server.get("/", middleware! { /* ... */ }) and server.get("/api/widgets", middleware! { /* ... */ }). The api key was being moved into middleware closure for the first endpoint, so there was a move error in the second endpoint.

I solved the error by using an Arc<String> and wrapping it around the api key. Then I cloned the Arc for each of the two endpoints, and dereferenced them to get access to the api key.

But I'm still not sure I did the right thing! Cloning a reference counter around a resource for every single endpoint doesn't scale well at all, so I'm hoping there's a better way that I just don't know yet. I'm really new to Rust, so I would benefit from a better example to know I'm doing it the right way. It would be great if the example had two endpoints defined that both relied on the same non-Copy type.

@jolhoeft
Copy link
Member

The Arc<String> approach is basically what you need to do if you wish to capture the variable in the closure created by the middleware! macro.

One way around this is to use the server data, set with Nickel::with_data. See the no_macro_custom_data.rs and integration_testing.rs examples for how it is used. The middleware macro is somewhat fragile with server data (fragile in general, actually) so the no_macro_custom_data.rs example would be a good model to follow.

@andrewjensen
Copy link

@jolhoeft thanks for the tips! The context helps me understand the examples better now.

I'd be happy to contribute to the examples to point other beginners in the right direction. I originally found the moved_ownership.rs example because the Rust compiler told me my app had an issue with a moved value, which made that example stand out.

I could add some comments to the file directing beginners to some other examples. I think route_data.rs and no_macro_custom_data.rs both demonstrate the solution most concisely, so I could reference both of them. Alternatively, I could add another example like moved_ownership_multiple.rs, where an Arc<String> is necessary, but I think a few comments would do.

What do you think would be best?

@jolhoeft
Copy link
Member

jolhoeft commented May 1, 2019

Sorry I missed this. If you are still interested, a few comments on the existing example would be great. The additional example is good to.

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

4 participants