为什么尝试有条件地包装我的activx web应用程序时出现此错误



我试图有条件地用CORS包装我的应用程序,但我遇到了错误。

use actix_cors::Cors;
use actix_web::{http::header, App, HttpServer};
use std::{net::SocketAddr, sync::Arc};
use common::config::Config;
pub async fn start(config: Arc<Config>) -> std::io::Result<()> {
let config_app = Arc::clone(&config);
let server = HttpServer::new(move || {
let mut app = App::new();
if config_app.cors.enabled {
app = app.wrap( // the error is here, read below
Cors::default()
.allowed_origin("http://localhost:8080")
.allowed_methods(vec!["GET", "POST"])
.allowed_headers(vec![header::AUTHORIZATION, header::ACCEPT])
.allowed_header(header::CONTENT_TYPE)
.supports_credentials()
.max_age(3600),
)
}
app
});
let addr = SocketAddr::from(([127, 0, 0, 1], config.port));
server.bind(addr)?.run().await
}

错误是:

mismatched types
expected struct `actix_web::App<actix_web::app_service::AppEntry>`
found struct `actix_web::App<impl actix_web::dev::ServiceFactory<actix_web::dev::ServiceRequest, Config = (), Response = actix_web::dev::ServiceResponse<actix_web::body::EitherBody<actix_web::body::BoxBody>>, Error = actix_web::Error, InitError = ()>>` rustc E0308
app.rs(355, 9): the found opaque type
server.rs(13, 23): expected due to this value

为什么?

发生错误的原因是变量app的具体类型为App<AppEntry>,而app的类型永远不会更改。但是App::wrap不返回App<AppEntry>,它返回某种App<S>,其中S是一个具体类型,但我们不知道它的名称,也不知道它满足什么特征。Rust称之为";不透明型";。

但由于它没有类型App<AppEntry>,我们无法将其分配给app,因此出现了错误。

除非actix_web有一些我不知道的机制来绕过这一点,否则我认为你最好的选择是考虑";"包裹";服务器转换为不同的函数,并在需要时从start调用该函数,类似于以下内容:

// I just mocked this up to satisfy the compiler
pub struct Config {
cors_enabled: bool,
port: u16,
}
pub async fn start(config: Arc<Config>) -> std::io::Result<()> {
let addr = SocketAddr::from(([127, 0, 0, 1], config.port));
if config.cors_enabled {
return start_with_cors(addr, config).await;
}
let server = HttpServer::new(move || App::new());
server.bind(addr)?.run().await
}
async fn start_with_cors(addr: SocketAddr, _config: Arc<Config>) -> std::io::Result<()> {
let server = HttpServer::new(move || {
App::new().wrap(
Cors::default()
.allowed_origin("http://localhost:8080")
.allowed_methods(vec!["GET", "POST"])
.allowed_headers(vec![header::AUTHORIZATION, header::ACCEPT])
.allowed_header(header::CONTENT_TYPE)
.supports_credentials()
.max_age(3600),
)
});
server.bind(addr)?.run().await
}

最新更新