Understanding lifetimes with structs as arguments

I'm trying to declare the val argument in this function:

struct User<'a> {
    mac: String,
    data: Vec<&'a str>
}

#[post("/filter", format = "application/json", data = "<val>", rank = 2)]
pub async fn get_user_data(val: User) -> (Status, &'static str) {
    redis_service::filter(&val.mac, val.data);
    return (Status::Ok, "200 - OK");
}

But I don't really understand lifetime parameter and don't know what to add on User.

error[E0277]: the trait bound `information_controller::User<'_>: FromData<'_>` is not satisfied
  --> src/controller/information_controller.rs:56:35
   |
56 | pub async fn get_user_data(val: User) -> (Status, &'static str) {
   |                                   ^^^^ the trait `FromData<'_>` is not implemented for `information_controller::User<'_>`
   |
   = help: the following other types implement trait `FromData<'r>`:
             &'r RawStr
             &'r [u8]
             &'r str
             Capped<&'r RawStr>
             Capped<&'r [u8]>
             Capped<&'r str>
             Capped<Cow<'impl0, str>>
             Capped<TempFile<'impl0>>
           and 11 others

How can I fix this?

The simplest solution is to "ignore" the lifetime parameter while still acknowledging its existence: User<'_>

This is equivalent with the full declaration

fn foo<'a>(user: User<'a>) -> …

If you have any constraints on the lifetime parameter or you need to link it to another one, then you must use the explicit (second) form.

2 Likes

If I do the first solution for struct User<'a> { the compiler gives me the error, that I can't use '_. If I use '_ here: pub async fn get_user_data(val: User<'_>) -> (Status, &'static str) { then the compiler returns the same error that is shown in my question.

The second error comes also if I do the second solution.

There are basically multiple questions here

First:

H2CO3's post answers this part. If the type definition has a lifetime, you should also add that to wherever you use it. Just like how instead of a val: Vec parameter you would write val: Vec<SomeType>, you need val: User<'some_lifetime>. For more info the Rust book and in particular the part about lifetimes may be helpful: Validating References with Lifetimes.

Second:

The error is unrelated to lifetimes.

error[E0277]: the trait bound `information_controller::User<'_>: FromData<'_>` is not satisfied
  --> src/controller/information_controller.rs:56:35
   |
56 | pub async fn get_user_data(val: User) -> (Status, &'static str) {
   |                                   ^^^^ the trait `FromData<'_>` is not implemented for `information_controller::User<'_>`

In other words: "the type information_controller::User<'_> needs to implement the trait FromData<'_>, but it doesn't". You seem to be using the Rocket crate here. When asking a question it's best to include any relevant crates and the versions you're using, because they're often very relevant to the question being asked, as is the case here. Rocket's docs go over FromData here: Requests - Rocket Programming Guide and here: FromData in rocket::data - Rust

Ah thanks, I fixed the error with your first link!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.