使用Axum和Tokio下载文件可以使用什么签名?



我正在使用axum和下面的代码(在这里找到)来下载文件:

use axum::{
body::StreamBody,
http::{header, StatusCode},
response::{Headers, IntoResponse},
routing::get,
Router,
};
use std::net::SocketAddr;
use tokio_util::io::ReaderStream;
#[tokio::main]
async fn main() {
let app = Router::new().route("/", get(handler));
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
async fn handler() -> impl IntoResponse {
// `File` implements `AsyncRead`
let file = match tokio::fs::File::open("Cargo.toml").await {
Ok(file) => file,
Err(err) => return Err((StatusCode::NOT_FOUND, format!("File not found: {}", err))),
};
// convert the `AsyncRead` into a `Stream`
let stream = ReaderStream::new(file);
// convert the `Stream` into an `axum::body::HttpBody`
let body = StreamBody::new(stream);
let headers = Headers([
(header::CONTENT_TYPE, "text/toml; charset=utf-8"),
]);
Ok((headers, body))
}

一切正常。但是我找不到一种方法来移动下面的代码在一个单独的函数:

let file = match tokio::fs::File::open("Cargo.toml").await {
Ok(file) => file,
Err(err) => return Err((StatusCode::NOT_FOUND, format!("File not found: {}", err))),
};

我想在这个函数中同时使用tokio::fs::Filehttps://crates.io/crates/rust-s3方法。

所以我需要一个"通用类型"我想是AsyncRead

函数的签名应该是什么?

I tried with:

use tokio::io::AsyncRead;
pub struct Player {
db: Arc<DB>
}
impl Handler {
pub async fn player_pdf(
&self,
id: &str,
) -> Result<&(dyn AsyncRead)> {
//...use id here...
let file = &tokio::fs::File::open("player.pdf").await?;
Ok(file)
}
}

但是我得到错误:

error[E0308]: mismatched types
|
55  |         Ok(file)
|         -- ^^^^
|         |  |
|         |  expected reference, found struct `tokio::fs::File`
|         |  help: consider borrowing here: `&file`
|         arguments to this enum variant are incorrect
|
= note: expected reference `&dyn tokio::io::AsyncRead`
found struct `tokio::fs::File`

我尝试了:let file = &tokio::fs::File::open("player.pdf").await?;,我得到:

error[E0515]: cannot return value referencing temporary value
|
43 |         let file = &tokio::fs::File::open(...
|                     --------------------------- temporary value created here
...
55 |         Ok(file)
|         ^^^^^^^^ returns a value referencing data owned by the current function

我可以用什么?

返回一个通用的"box "Value可能是这里的解决方案:

impl Handler {
pub async fn player_pdf(
&self,
id: &str,
) -> Result<Box<dyn AsyncRead>> {
//...use id here...
Ok(Box::new(tokio::fs::File::open("player.pdf").await?))
}
}

现在没有悬空引用,它被封装并完全拥有。

相关内容

  • 没有找到相关文章

最新更新