#rust #rust-actix #rust-async-std
Вопрос:
У меня есть переменная, которая будет контролировать, какая функция является поведением моего веб-приложения по умолчанию, но обе функции есть, и она мне не позволит, потому что они разные. async
Что-то вроде этого воспроизводит ту же ошибку: https://play.rust-lang.org/?version=stableamp;mode=debugamp;edition=2018amp;gist=db0269ef4852a94438e6d4925ca83d3b
Теперь мои вопросы таковы:
- Как мне решить эту проблему, чтобы совпадение работало?
- Есть ли лучший способ программно настроить поведение сервера по умолчанию в actix на основе флагов пользовательского интерфейса командной строки? Для контекста это более или менее то, что у меня есть:
main.rs
// Matches comes from the command line
let a = match matches.occurrences_of("default"){
1 => handlers::forward,
_ => handlers::resource_not_found,
};
... setting up db, auth etc
HttpServer::new(move || {
App::new()
... lots of routes
.default_service(web::route().to(a))
handlers.rs
pub async fn resource_not_found(
) -> Result<HttpResponse, Error> {
Ok(HttpResponse::NotFound().body("Resource does not exist"))
}
pub async fn forward(
) -> Result<HttpResponse, Error> {
Ok(HttpResponse::Ok().body("Resource does exist"))
}
Ответ №1:
Как мне решить эту проблему, чтобы совпадение работало
Вы можете создать два замыкания, которые оба возвращают упакованное будущее, и принудить их к указателю функции:
use std::pin::Pin;
use std::future::Future;
let a: fn() -> Pin<Box<dyn Future<Output = Result<HttpResponse, Error>>>> =
match matches.occurrences_of("default") {
1 => || Box::pin(handlers::forward()),
_ => || Box::pin(handlers::resource_not_found()),
};
Если функции действительно настолько просты, то вы можете избежать бокса и вернуться std::future::Ready
:
use std::pin::Pin;
use std::future::{Future, Ready, ready};
let a: fn() -> Ready<Result<HttpResponse, Error>> =
match matches.occurrences_of("default") {
1 => || handlers::forward,
_ => || handlers::resource_not_found,
};
// handlers.rs
pub fn resource_not_found(
) -> Ready<Result<HttpResponse, Error>> {
ready(Ok(HttpResponse::NotFound().body("Resource does not exist")))
}
pub fn forward(
) -> Ready<Result<HttpResponse, Error>> {
ready(Ok(HttpResponse::Ok().body("Resource does exist")))
}
Есть ли лучший способ программно настроить поведение сервера по умолчанию в actix на основе флагов пользовательского интерфейса командной строки
Вы могли бы выполнить сопоставление внутри нового обработчика, а не снаружи:
let x = matches.occurrences_of("default");
let a = move || async move {
match x {
1 => handlers::forward().await,
_ => handlers::resource_not_found().await,
}
};
Теперь вместо дополнительного распределения и динамической отправки на вызов вам просто нужно сопоставить целое число.