How to pass data from request to response without copying in actix_web

802 views Asked by At

I have a User structure that is deserialized from the request body. I want to fill the data of the User structure (field name) according to the data received from the database and return the response.

  1. Without copying, borrow the username from the database data, which is stored in the global structure
  2. Return a response of the same User structure with a filled-in name

I use tokio::task::spawn_blocking because there are blocking operations in the real project

lazy_static! {
    pub static ref USER_DATA: Mutex<Arc<HashMap<String, String>>> = Mutex::new(Arc::new(Default::default()));
}

#[derive(Deserialize, Serialize, Default)]
struct User<'a> {
    id: &'a str,

    #[serde(skip_deserializing)]
    name: &'a str
}

struct Response<'a> {
    user: web::Json<User<'a>>,
    common_data: Arc<HashMap<String, String>>
}

impl Response<'_> {
    pub fn fill_user(mut self) -> Self {
        self.user.name = self.common_data.get(self.user.id).unwrap();
        self
    }
}

impl Responder for Response<'_> {
    fn respond_to(self, req: &HttpRequest) -> HttpResponse {
        HttpResponse::build(StatusCode::OK).body(serde_json::to_string(&self.user).unwrap())
    }
}

async fn calculate(req: HttpRequest, user: web::Json<User<'static>>) -> impl Responder {

    let mut resp = Response {
        user,
        common_data: USER_DATA.lock().await.clone()
    };

    tokio::task::spawn_blocking(move || {
        resp.fill_user()
    }).await.unwrap()

}

Now I am getting this error

error: implementation of `_::_serde::Deserialize` is not general enough
  --> src\main.rs:62:46
   |
62 |             .route("/calculate", web::post().to(calculate))
   |                                              ^^ implementation of `_::_serde::Deserialize` is not general enough
   |
   = note: `User<'static>` must implement `_::_serde::Deserialize<'0>`, for any lifetime `'0`...
   = note: ...but `User<'_>` actually implements `_::_serde::Deserialize<'1>`, for some specific lifetime `'1`
0

There are 0 answers