如何正确折叠多部分字段?

时间:2019-07-19 13:25:46

标签: rust rust-actix actix-web

我的尝试是在将接收到的图像保存到fs之前实现图像预处理器。

应该从actix-multipart接收。但是我不明白自己的尝试出了什么问题:

fn handle_file_from_multipart(field: Field) -> impl Future<Item=HttpResponse, Error=actix_http::error::Error> {
    Either::B(field.fold((), |_, bytes| {
        let fmt = match image::guess_format(&bytes) {
            Ok(fmt) => fmt,
            Err(e) => {
                eprintln!("handle_file_from_multipart: image::guess_format : {:?}", e);
                return Err(MultipartError::Payload(error::PayloadError::Io(std::io::Error::new(std::io::ErrorKind::Other, format!("handle_file_from_multipart: image::guess__format : {:?}", e)))));
            }
        };
        let ext = match fmt {
            ImageFormat::PNG => "png",
            ImageFormat::JPEG => "jpg",
            ImageFormat::GIF => "gif",
//                    ImageFormat::WEBP => "webp",
            ImageFormat::PNM => "pnm",
//                    ImageFormat::TIFF => "tiff",
            ImageFormat::TGA => "tga",
            ImageFormat::BMP => "bmp",
            ImageFormat::ICO => "ico",
            ImageFormat::HDR => "hdr",

            _ => {
                eprintln!("handle_file_from_multipart: fmt == \"{:?}\" is unsupported", fmt);
                return Err(MultipartError::Payload(error::PayloadError::Io(std::io::Error::new(std::io::ErrorKind::Other, format!("handle_file_from_multipart: \"{:?}\" is unsupported", fmt)))));
            }
        };

        let mut pb = get_random_name();
        let mut pbthumb = pb.clone();
        pb.set_extension(&ext);
        pbthumb.set_extension("thumb.".to_string() + &ext);

        actix_web::web::block(move || {
            match image::load_from_memory(&bytes) {
                Ok(img) => {
                    match img.thumbnail(100,100).save(pbthumb) {
                        Ok(_) => {},
                        Err(e) => {
                            eprintln!("handle_file_from_multipart: thumbnail.save : {:?}", e);
                            return Err(MultipartError::Payload(error::PayloadError::Io(std::io::Error::new(std::io::ErrorKind::Other, format!("handle_file_from_multipart: thumbnail.save : \"{:?}\"", e)))));
                        }
                    }
                    match img.save(pb) {
                        Ok(_) => {},
                        Err(e) => {
                            eprintln!("handle_file_from_multipart: img.save : {:?}", e);
                            return Err(MultipartError::Payload(error::PayloadError::Io(std::io::Error::new(std::io::ErrorKind::Other, format!("handle_file_from_multipart: img.save : \"{:?}\"", e)))));
                        }
                    }
                },
                Err(e) => {
                    eprintln!("handle_file_from_multipart: image::load_from_memory : {:?}", e);
                    return Err(MultipartError::Payload(error::PayloadError::Io(std::io::Error::new(std::io::ErrorKind::Other, format!("handle_file_from_multipart: image::load_from_memory : \"{:?}\"", e)))));
                }
            };
            Ok(pb.to_str().unwrap().to_string())
        })
            .map_err(|e: error::BlockingError<MultipartError>| {
                match e {
                    error::BlockingError::Error(e) => e,
                    error::BlockingError::Canceled => MultipartError::Incomplete
                }
            })
    })
        .map(|s| s)
        .map_err(|e| {
            eprintln!("handle_file_from_multipart: actix_web::web::block : \"{:?}\"", e);
            error::ErrorInternalServerError(e)
        })
//        .map(|_, s| s.to_string())
//        .map_err(|e| {
//            eprintln!("handle_file_from_multipart failed: {:?}", e);
//            error::ErrorInternalServerError(e)
//        })
    )

}


fn upload_multipart((mp, state): (Multipart, Data<Form>)) -> Box<dyn Future<Item = HttpResponse, Error = actix_http::error::Error>> { //Error = form_data::Error>> {
//    println!("state: {:?}", state);
    Box::new( 
        mp
            .map_err(error::ErrorInternalServerError)
            .map(|field| {
                handle_file_from_multipart(field).into_stream()
            })
            .flatten()
            .collect()
            .map(|sizes| HttpResponse::Created().finish())
            .map_err(|e| {
                println!("failed: {}", e);
                e
            })
    )
}
  

错误[E0308]:类型不匹配-> src / main.rs:93:9       | 93 | / actix_web :: web :: block(移动|| {94 | |匹配图片:: load_from_memory(&bytes){95 | |
  Ok(img)=> {96 | |比赛   img.thumbnail(100,100).save(pbthumb){... | 122 | |
  } 123 | | })       | | ________________ ^预期枚举std::result::Result,找到结构futures::future::map_err::MapErr       |       =注意:预期类型std::result::Result<(), actix_multipart::error::MultipartError>                  找到类型futures::future::map_err::MapErr<impl futures::future::Future, [closure@src/main.rs:118:22: 123:14]>

它似乎与https://github.com/actix/examples/blob/master/multipart/src/main.rs完全相同  但是...出了点问题,我不明白。

src / main.rs https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=bf05480733c71b0d50db6d833ebb63c1 Cargo.toml http://notes.io/66Se

0 个答案:

没有答案