我是一名Rust新手,但从C++的Angular /背景来看,我是一名编程老手,所以这可能解释了我的大部分困惑.
在它的核心,我有一个令人麻木的简单问题要解决.然而,铁 rust 中看似最基本的东西却让我陷入了麻烦的老鼠窝.
我有一些代码:
pub fn my_application(cfg: &mut web::ServiceConfig) {
let auth = HttpAuthentication::bearer(validate_bearer);
...
我希望对其进行重构.我想要使用我自己的定制中间件,而不是使用‘Actix’HttpAuthentication::Beader中间件.
所以all我想做的就是把‘let auth=...’行,并将等号后面的内容放入另一个文件中的一个函数中.
How hard could that be?个
因此,我try 了显而易见的方法: 在新文件中:
// WONT repeat 'use' statements in rest, but included once in case you try to compile)
use actix_web::dev::ServiceRequest;
use actix_web::Error;
use actix_web_httpauth::extractors::bearer::BearerAuth;
use actix_web_httpauth::middleware::HttpAuthentication;
use core::future::Future;
use crate::server::auth::common::validate_bearer;
// in C++, you would might say auto, or some such
pub fn create_auth_middleware_1()
{
let auth = HttpAuthentication::bearer(validate_bearer);
auth
}
但失败了:
^^^^ expected `()`, found `HttpAuthentication<BearerAuth, ...>`
OK-所以Rust没有函数声明的自动或类型演绎(或者我错过了这方面的语法).很好.
接下来,我try 了"泛型".
pub fn create_auth_middleware_2<T>() -> T
{
let auth = HttpAuthentication::bearer(validate_bearer);
auth
}
这将导致:
^^^^ expected type parameter `T`, found `HttpAuthentication<BearerAuth, ...>`
Next--try 了T上的一系列‘where’子句来指定它,灵感来自于服务‘print’函数上的声明--这是一个非常复杂的类型声明.例如:
// ONE TIME ADD 'uses' but keep around for other samples that need it...
use actix_service::boxed::{BoxService};
use actix_web::body::MessageBody;
use actix_web::dev::{Payload, Service, ServiceResponse, Transform};
use actix_web::http::header::Header;
use actix_web::{FromRequest, HttpRequest};
pub fn create_auth_middleware_3<T>() -> T
where T: Transform<S, ServiceRequest>,
S: Service<ServiceRequest, Response = ServiceResponse, Error = Error> {
let auth = HttpAuthentication::bearer(validate_bearer);
auth
}
也许这一次来自编译器的提示!
auth
| ^^^^ expected type parameter `T`, found `HttpAuthentication<BearerAuth, ...>`
|
= note: expected type parameter `T`
found struct `HttpAuthentication<BearerAuth, fn(..., ...) -> ... {validate_bearer}>`
the full type name has been written to ....
所以我try 了编译器写入该文件的实际类型
pub fn create_auth_middleware_4() -> HttpAuthentication<BearerAuth, fn(ServiceRequest, BearerAuth) -> impl futures::Future<Output = std::result::Result<ServiceRequest, actix_web::Error>> {validate_bearer}> {
let auth = HttpAuthentication::bearer(validate_bearer);
auth
}
结果是:
error[E0747]: constant provided when a type was expected
--> src/server/auth/middleware.rs:37:69
|
37 | ...h, fn(ServiceRequest, BearerAuth) -> impl futures::Future<Output = std::result::Result<ServiceRequest, actix_web::Error>> {validate_bearer}...
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
好的--也许Rust不喜欢它作为类型的一部分而写的明确的{validate_bearer}
个东西.
pub fn create_auth_middleware_5() -> HttpAuthentication<BearerAuth, fn(ServiceRequest, BearerAuth) -> impl futures::Future<Output = std::result::Result<ServiceRequest, actix_web::Error>> > {
let auth = HttpAuthentication::bearer(validate_bearer);
auth
}
结果是:
error[E0562]: `impl Trait` only allowed in function and inherent method return types, not in `fn` pointer return types
我要做的这件事--把一个表达式包装成一个单独的函数,放在另一个文件中,这在我使用过的几乎所有编程语言(Python、Prolog、C、C++、Java、TypeScrip、JavaScript、Ruby、Lisp)中都是微不足道的.我相信在Rust中也有一个非常简单的方法来做到这一点,但我没有找到它.请帮我看看我遗漏了什么,以及如何对Rust代码进行这种基本的因式分解.