Using persist with actix multiform tempfile

Hello! I'm using the actix multiform module and I've defined this form:

pub struct DbUpload {
    db_file: TempFile,
    last_modify_ts: Text<i64>,
    compression: Text<String>,
    original_hash: Text<String>,
    index: Text<i64>,
    length: Text<i64>,
    nonce: Text<i64>,

and later I try to do

let stored_file =  form.db_file.file.persist(new_path);

but the compiler gives me this error

error[E0507]: cannot move out of dereference of `MultipartForm<DbUpload>`
   --> src/routes/
98  |     let stored_file =  form.db_file.file.persist(new_path);
    |                        ^^^^^^^^^^^^^^^^^ ----------------- value moved due to this method call
    |                        |
    |                        move occurs because value has type `NamedTempFile`, which does not implement the `Copy` trait

I checked their examples and it works there because they are using a vec instead of a single file. examples/forms/multipart/src/ at 887d3779f43e67fd7b3ea2af7e12e56f09d83357 · actix/examples · GitHub. Anyone could guide me about how to do it with a single file? Thanks

The error message only makes sense if form comes from a reference, such as if the function signature were this:

async fn save_files(
    &mut MultipartForm(form): &mut MultipartForm<DbUpload>,
) -> Result<impl Responder, Error> {

But I can't say for sure without seeing the whole function.

Thanks! I made a smaller replica of my code since I have authentication logic but tried and this example produces the same error

pub async fn backup_upload(
    form: MultipartForm<DbUpload>,
    request: HttpRequest,
    pool: web::Data<PgPool>,
) -> impl Responder {
    let user_id = "user_id".to_string();

    let new_file_name = format!("{}.db.temp", digest(user_id.clone()));
    let new_path = format!(
    let stored_file =  form.db_file.file.persist(new_path);

I see what happened, now. Try this change:

  pub async fn backup_upload(
-     form: MultipartForm<DbUpload>,
+     MultipartForm(form): MultipartForm<DbUpload>,
      request: HttpRequest,
      pool: web::Data<PgPool>,
  ) -> impl Responder {

The version you have is accessing the member variable through MultipartForm's Deref implementation, which only gives you a reference.

To move out of it, you need to bypass the Deref implementation and, in the example above, destructure it with pattern matching. The into_inner function would work, too.


Thank you very much! It worked. Is always good to learn new things.

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.