缺少 trait `actix_service::Service` 的泛型 --> src/middleware.rs:57:8

如何解决缺少 trait `actix_service::Service` 的泛型 --> src/middleware.rs:57:8

我如何实现特征?在运行货物构建时,我收到此错误。 我也注释掉了 type Request = ServiceRequest;。这将如何影响代码?我在 Cargo.toml 中将 actix-service 更新为 2.0.0-beta.2,然后构建失败。

error[E0107]: missing generics for trait `actix_service::Service`
  --> src/middleware.rs:57:8
   |
57 |     S: Service<Response = ServiceResponse<B>,Error = Error> + 'static,|        ^^^^^^^ expected 1 type argument
   |
note: trait defined here,with 1 type parameter: `Req`
  --> /home/samarpan/.cargo/registry/src/github.com-1ecc6299db9ec823/actix-service-2.0.0-beta.5/src/lib.rs:85:11
   |
85 | pub trait Service<Req> {
   |           ^^^^^^^ ---
help: use angle brackets to add missing type argument
   |
57 |     S: Service<Req><Response = ServiceResponse<B>,|               ^^^^^

这是我的中间件.rs -

#![allow(clippy::type_complexity)]

use std::cell::RefCell;
use std::ops::{Deref,DerefMut};
use std::pin::Pin;
use std::rc::Rc;
use std::sync::Arc;
use std::task::{Context,Poll};

use futures::future::{ok,Ready};
use futures::Future;

use actix_service::{Service,Transform};
use actix_web::{
    dev::ServiceRequest,dev::ServiceResponse,Error,HttpMessage,HttpResponse,Result,};

use casbin::prelude::{TryIntoAdapter,TryIntoModel};
use casbin::{CachedEnforcer,CoreApi,Result as casbinResult};

#[cfg(feature = "runtime-tokio")]
use tokio::sync::RwLock;

#[cfg(feature = "runtime-async-std")]
use async_std::sync::RwLock;

#[derive(Clone)]
pub struct casbinVals {
    pub subject: String,pub domain: Option<String>,}

#[derive(Clone)]
pub struct casbinService {
    enforcer: Arc<RwLock<CachedEnforcer>>,}

impl casbinService {
    pub async fn new<M: TryIntoModel,A: TryIntoAdapter>(m: M,a: A) -> casbinResult<Self> {
        let enforcer: CachedEnforcer = CachedEnforcer::new(m,a).await?;
        Ok(casbinService {
            enforcer: Arc::new(RwLock::new(enforcer)),})
    }

    pub fn get_enforcer(&mut self) -> Arc<RwLock<CachedEnforcer>> {
        self.enforcer.clone()
    }

    pub fn set_enforcer(e: Arc<RwLock<CachedEnforcer>>) -> casbinService {
        casbinService { enforcer: e }
    }
}

impl<S,B> Transform<S,B> for casbinService
where
    S: Service<Response = ServiceResponse<B>,S::Future: 'static,B: 'static,{
    //type Request = ServiceRequest;
    type Response = ServiceResponse<B>;
    type Error = Error;
    type InitError = ();
    type Transform = casbinMiddleware<S>;
    type Future = Ready<Result<Self::Transform,Self::InitError>>;

    fn new_transform(&self,service: S) -> Self::Future {
        ok(casbinMiddleware {
            enforcer: self.enforcer.clone(),service: Rc::new(RefCell::new(service)),})
    }
}
impl Deref for casbinService {
    type Target = Arc<RwLock<CachedEnforcer>>;

    fn deref(&self) -> &Self::Target {
        &self.enforcer
    }
}

impl DerefMut for casbinService {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.enforcer
    }
}

pub struct casbinMiddleware<S> {
    service: Rc<RefCell<S>>,enforcer: Arc<RwLock<CachedEnforcer>>,}

impl<S,B> Service<B> for casbinMiddleware<S>
where
    S: Service<Response = ServiceResponse<B>,{
    //type Request = ServiceRequest;
    type Response = ServiceResponse<B>;
    type Error = Error;
    type Future = Pin<Box<dyn Future<Output = Result<Self::Response,Self::Error>>>>;

    fn poll_ready(&self,cx: &mut Context<'_>) -> Poll<Result<(),Self::Error>> {
        self.service.poll_ready(cx)
    }

    fn call(&mut self,req: ServiceRequest) -> Self::Future {
        let cloned_enforcer = self.enforcer.clone();
        let mut srv = self.service.clone();

        Box::pin(async move {
            let path = req.path().to_string();
            let action = req.method().as_str().to_string();
            let option_vals = req.extensions().get::<casbinVals>().map(|x| x.to_owned());
            let vals = match option_vals {
                Some(value) => value,None => {
                    return Ok(req.into_response(HttpResponse::Unauthorized().finish().into_body()))
                }
            };
            let subject = vals.subject.clone();

            if !vals.subject.is_empty() {
                if let Some(domain) = vals.domain {
                    let mut lock = cloned_enforcer.write().await;
                    match lock.enforce_mut(vec![subject,domain,path,action]) {
                        Ok(true) => {
                            drop(lock);
                            srv.call(req).await
                        }
                        Ok(false) => {
                            drop(lock);
                            Ok(req.into_response(HttpResponse::Forbidden().finish().into_body()))
                        }
                        Err(_) => {
                            drop(lock);
                            Ok(req.into_response(HttpResponse::BadGateway().finish().into_body()))
                        }
                    }
                } else {
                    let mut lock = cloned_enforcer.write().await;
                    match lock.enforce_mut(vec![subject,action]) {
                        Ok(true) => {
                            drop(lock);
                            srv.call(req).await
                        }
                        Ok(false) => {
                            drop(lock);
                            Ok(req.into_response(HttpResponse::Forbidden().finish().into_body()))
                        }
                        Err(_) => {
                            drop(lock);
                            Ok(req.into_response(HttpResponse::BadGateway().finish().into_body()))
                        }
                    }
                }
            } else {
                Ok(req.into_response(HttpResponse::Unauthorized().finish().into_body()))
            }
        })
    }
}

原始回购链接 - https://github.com/casbin-rs/actix-casbin-auth

我的更改 - https://github.com/smrpn/actix-casbin-auth/tree/feature/bumpactixweb

解决方法

Service trait 有一个必需的泛型类型参数,但您没有设置它。我们在您实施 Service(通过将其从 Service 更改为 Service<B>)和 Transform(通过将其从 Transform<S> 更改为 { {1}}),但是您没有在使用 Transform<S,T> 作为特征边界的地方更改它(即 Service)。遵循也应从 S: Service<...> 更改为 S: Service<Request = ...> 的其他更改。

请注意,这将修复您提到的错误,但不会修复其他错误。我对 S: Service<B,Request = ...> 不熟悉,但从我看到的情况来看,在您应该将 actix-service 更改为 Transform<S>Transform<S,ServiceRequest> 为 {{ 1}} 和 ServiceService<ServiceRequest>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?