Как решить эту ошибку функции типа возврата в Rust - PullRequest
0 голосов
/ 07 апреля 2020

Я создаю ржавое веб-приложение. Я новичок в этом, и я пытаюсь сделать запросы API и передать результат из запроса в качестве ответа на веб-представление. Есть файлы main.rs, route.rs и common.rs. В основном файл main.rs вызывает соответствующий маршрут, а затем route вызывает функцию.

Но в файле route.rs есть ошибка с функцией.

error[E0277]: the trait bound `fn() -> impl std::future::Future {<search::routes::get_token as actix_web::service::HttpServiceFactory>::register::get_token}: actix_web::handler::Factory<_, _, _>` is not satisfied
  --> src\search\routes.rs:20:10
   |
20 | async fn get_token() -> Result<String, reqwest::Error> {
   |          ^^^^^^^^^ the trait `actix_web::handler::Factory<_, _, _>` is not implemented for `fn() -> impl std::future::Future {<search::routes::get_token as actix_web::service::HttpServiceFactory>::register::get_token}`

Как это исправить ??

route.rs

use crate::search::User;
use actix_web::{get, post, put, delete, web, HttpResponse, Responder};
use serde_json::json;
extern crate reqwest;
extern crate serde;
mod bfm;
mod common;

#[get("/token")]
async fn get_token() -> Result<String, reqwest::Error> {

    let set_token = common::authenticate(); 
    // let set_token = common::get_rust_posts();
    return set_token.await;
    //HttpResponse::Ok().json(set_token)
}

common.rs

extern crate reqwest;
use reqwest::header::HeaderMap;
use reqwest::header::AUTHORIZATION;
use reqwest::header::CONTENT_TYPE;

pub async fn authenticate() -> Result<String, reqwest::Error> {

    fn construct_headers() -> HeaderMap {
        let mut headers = HeaderMap::new();

        headers.insert(AUTHORIZATION, "Basic bghythjuikyt==".parse().unwrap());
        headers.insert(CONTENT_TYPE, "application/x-www-form-urlencoded".parse().unwrap());

        assert!(headers.contains_key(AUTHORIZATION));
        assert!(!headers.contains_key(CONTENT_TYPE));

        headers
    }

    let client = reqwest::Client::new();

    let reszr = client.post("https://api.test.com/auth/token")
    .headers(construct_headers())
    .body("grant_type=client_credentials")
        .send()
        .await?
        .text()
        .await;

        return reszr;
}

1 Ответ

1 голос
/ 07 апреля 2020

Прежде всего, пожалуйста, прочитайте: https://actix.rs/docs/errors/

-

Вы внедрили ResponseError для reqwest::Error?

Вы должны реализовать черту ResponseError, потому что фреймворк должен что-то ответить в случае, если Result равен Err.

Вот пример

impl ResponseError for Error {
    fn error_response(&self) -> HttpResponse {
        match self.kind_ref() {
            ErrorKind::HttpResponse { msg, code, real } => {
                println!("{}", real);

                HttpResponse::build(code.to_owned()).json(json!({
                    "status": false,
                    "msg": msg
                }))
            }
            _ => {
                println!("{}", self);

                HttpResponse::build(StatusCode::INTERNAL_SERVER_ERROR).finish()
            }
        }
    }
}

Error в этот случай - моя пользовательская ошибка, которая содержит msg, code, real, но логика c должна быть аналогичной в вашем случае.

-

ОБНОВЛЕНИЕ: после @Masklinn комментарий о error[E0117]: only traits defined in the current crate can be implemented for arbitrary types

Код выше работает только на пользовательских Error, которыми вы владеете.

Что вы можете сделать:

  • отображение reqwest::Error в Error, которое уже реализует ResponseError. Вы можете проверить список реализаций здесь: https://docs.rs/actix-web/3.0.0-alpha.1/actix_web/trait.ResponseError.html#implementors

  • создать пользовательский Error, который включает reqwest::Error (и другие ошибки в вашем коде) и внедрить ResponseError на нем (это в основном то же самое / похоже на первый)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...