在 actix-web 中使用重定向或命名文件进行响应

问题描述 投票:0回答:1

我有一个使用

Rust
actix-web
编写的小型后端应用程序。我想要一个类似下面的功能。

async fn function(var: bool) -> impl Responder {
    if var {
        Redirect::to("link")
    } else {
        NamedFile::open_async("/file").await
    }
}

我收到错误

:`if` and `else` have incompatible types  expected `Redirect`, found future

我认为这可能可以通过将文件读入字符串并使用

HttpResponse
来完成。但既然
NamedFile
实现了
Responder
,是否有可能让它在这种设置下工作?

如果我去掉 if-else,它们都是有效的返回类型,但 if-else 语句的返回类型必须匹配。那么,在这种情况下是否可以不使用 if-else 呢?

编辑:链接的解决方案在这种情况下不起作用。将 impl Responder 更改为

Box<dyn Responder>
会导致特征边界失败。我收到以下错误消息:

the trait bound `std::boxed::Box<(dyn actix_web::Responder + 'static)>: actix_web::Responder` is not satisfied 

也许它可以修复,但我没有足够的 Rust 泛型经验来做到这一点。

if-statement rust actix-web
1个回答
0
投票

动态调度无法与

Responder
配合使用,但还有其他两种解决方案。

第一个是使用

Either
,它还通过转发到活动变体来实现
Responder

use actix_web::Either;

async fn function(var: bool) -> impl Responder {
    if var {
        Either::Left(Redirect::to("link"))
    } else {
        Either::Right(NamedFile::open_async("/file").await)
    }
}

第二个选择,正如您所说,是将它们转换为

HttpResponse
。他们有不同的体型,所以我们还需要转换体型:

async fn function(var: bool, request: HttpRequest) -> HttpResponse {
    if var {
        Redirect::to("link")
            .respond_to(&request)
            .map_into_boxed_body()
    } else {
        NamedFile::open_async("/file")
            .await
            .respond_to(&request)
            .map_into_boxed_body()
    }
}

HttpRequest
是一个提取器,因此您可以在处理函数中包含此参数。

© www.soinside.com 2019 - 2024. All rights reserved.