lifetimes do not match method in trait when get token from request

Viewed 1088

I am learning Rust. Now I am using this code to get the accessToken from the HTTP request header in Rust rocket:

use rocket::request::FromRequest;
use rocket::{Request, request};
use rocket::outcome::Outcome;
use rocket::http::Status;

struct Token(String);

#[derive(Debug)]
enum ApiTokenError {
    Missing,
    Invalid,
}

impl<'a, 'r> FromRequest<'a> for Token {
    type Error = ApiTokenError;

    fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
        let token = request.headers().get_one("token");
        match token {
            Some(token) => {
                // check validity
                Outcome::Success(Token(token.to_string()))
            }
            None => Outcome::Failure((Status::Unauthorized, ApiTokenError::Missing)),
        }
    }
}

When I compile the project, it shows an error like this:

error[E0195]: lifetime parameters or bounds on method `from_request` do not match the trait declaration
  --> src/token.rs:17:20
   |
17 |     fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
   |                    ^ lifetimes do not match method in trait

Where is the code going wrong and what should I do to fix this problem?

1 Answers

FromRequest is an async trait. You need to attach that marker, and make it async. You don't need to constrain the Request's value's lifetime, though (so you don't need two lifetime parameters; you can use '_):

#[rocket::async_trait]
impl<'r> FromRequest<'r> for Token {
    type Error = ApiTokenError;

     async fn from_request(request: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
         ...
     }
}
Related