微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

通过 FromRequest

如何解决通过 FromRequest

我在 Rust 中使用 Rocket Web 框架,并且我有一个数据库池 (DbConn)。

#[database("redirect-api")]
pub struct DbConn(diesel::PgConnection);

我已经能够将 DbConn 传递给每个路由,但是在尝试将它传递给由 from_request 调用函数时遇到了问题。在 get_redirects 中,我使用 ApiKey 结构,以及我如何理解它,Fromrequest 是检查输入的守卫。在 from_request 中,我调用 is_valid 函数但不能将它传递给 DbConn,就像我从路由调用 is_valid 一样,比如直接从 get_redirects 调用

我希望能够在 is_valid 函数中使用 DbConn,但是如果我尝试使用 &DbConn 会出现此错误

the trait `diesel::Connection` is not implemented for `fn(PooledConnection<<diesel::PgConnection as Poolable>::Manager>) -> DbConn {DbConn}`
   |
43 |         .load::<Token>(&DbConn)
   |                        ^^^^^^^ the trait `diesel::Connection` is not implemented for `fn(PooledConnection<<diesel::PgConnection as Poolable>::Manager>) -> DbConn {DbConn}`
   |
   = note: required because of the requirements on the impl of `LoadQuery<fn(PooledConnection<<diesel::PgConnection as Poolable>::Manager>) -> DbConn {DbConn},models::Token>` for `diesel::query_builder::SelectStatement<schema::tokens::table,query_builder::select_clause::DefaultSelectClause,query_builder::distinct_clause::NodistinctClause,query_builder::where_clause::WhereClause<diesel::expression::operators::Eq<schema::tokens::columns::token,diesel::expression::bound::Bound<diesel::sql_types::Text,std::string::String>>>,query_builder::order_clause::NoOrderClause,query_builder::limit_clause::LimitClause<diesel::expression::bound::Bound<BigInt,i64>>>`
#![feature(decl_macro)]
use rocket::{catchers,routes};

#[macro_use]
extern crate diesel;
#[macro_use]
extern crate rocket_contrib;
use diesel::prelude::*;
// --snip--

#[database("redirect-api")]
pub struct DbConn(diesel::PgConnection);
// --snip--

fn is_valid(key: &str) {
    // ... use key,hash is,etc
    // check if hash is in database
    // this function needs the database pool or DbConn
    // but it can't be passed through Fromrequest
}

impl<'a,'r> Fromrequest<'a,'r> for ApiKey {
    type Error = ApiKeyError;

    fn from_request(request: &'a Request<'r>) -> request::Outcome<Self,Self::Error> {
        let keys: Vec<_> = request.headers().get("x-api-key").collect();
        match keys.len() {
            0 => Outcome::Failure((Status::BadRequest,ApiKeyError::Missing)),1 if is_valid(keys[0]) => Outcome::Success(ApiKey(keys[0].to_string())),1 => Outcome::Failure((Status::BadRequest,ApiKeyError::Invalid)),_ => Outcome::Failure((Status::BadRequest,ApiKeyError::BadCount)),}
    }
}
// --snip--

#[get("/redirects")]
pub fn get_redirects(_key: ApiKey,conn: DbConn) -> String {
    // ... do database things with conn
    format!("something {}",some_value_from_db)
}

// --snip--

fn main() {
    rocket::ignite()
        .register(catchers![not_found])
        .attach(DbConn::fairing())
        .mount("/",routes![root,get_redirect])
        .launch();
}

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