Как вызвать функцию из другого файла и извлечь ее из Интернета - PullRequest
0 голосов
/ 02 апреля 2020

Я новичок в Rust и все еще учусь. Существует приложение ржавчины с main.rs и rout.rs. Файл main.rs имеет конфигурацию сервера, а route.rs содержит методы с путями.

main.rs

#[macro_use]
extern crate log;

use actix_web::{App, HttpServer};
use dotenv::dotenv;
use listenfd::ListenFd;
use std::env;

mod search;

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
    dotenv().ok();
    env_logger::init();

    let mut listenfd = ListenFd::from_env();
    let mut server = HttpServer::new(|| 
        App::new()
            .configure(search::init_routes)
    );

    server = match listenfd.take_tcp_listener(0)? {
        Some(listener) => server.listen(listener)?,
        None => {
            let host = env::var("HOST").expect("Host not set");
            let port = env::var("PORT").expect("Port not set");
            server.bind(format!("{}:{}", host, port))?
        }
    };

    info!("Starting server");
    server.run().await
}

rout.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;
use reqwest::Error;
use serde::{Deserialize};
use rocket_contrib::json::Json;
use serde_json::Value;
// mod bargainfindermax;

#[get("/users")]
async fn find_all() -> impl Responder {
    HttpResponse::Ok().json(
        vec![
            User { id: 1, email: "tore@cloudmaker.dev".to_string() },
            User { id: 2, email: "tore@cloudmaker.dev".to_string() },
        ]
    )
}

pub fn init_routes(cfg: &mut web::ServiceConfig) {
    cfg.service(find_all);
}

Теперь то, что я хочу я хочу получить API, используя метод в другом отдельном файле rs (fetch_test.rs) и направить его в файл rout.rs. Затем я хочу получить ответ из веб-браузера, запустив этот маршрут (ссылка).

Как я могу это делать ?? Я искал везде, но я не нашел ничего полезного. И иногда я также не понимал некоторые документы.

** Обновление.

fetch_test.rs

extern crate reqwest;
use hyper::header::{Headers, Authorization, Basic, ContentType};

pub fn authenticate() -> String {

fn construct_headers() -> Headers {
    let mut headers = Headers::new();
    headers.set(
        Authorization(
            Basic {
                username: "HI:ABGTYH".to_owned(),
                password: Some("%8YHT".to_owned())
            }
        )
     );
    headers.set(ContentType::form_url_encoded());
    headers
}

let client = reqwest::Client::new();
let resz = client.post("https://api.test.com/auth/token")
    .headers(construct_headers())
    .body("grant_type=client_credentials")
    .json(&map)
    .send()
    .await?;

}

Ошибки.


   Compiling sabre-actix-kist v0.1.0 (E:\wamp64\www\BukFlightsNewLevel\flights\APIs\sabre-actix-kist)
error[E0425]: cannot find value `map` in this scope
  --> src\search\routes\common.rs:28:12
   |
28 |     .json(&map)
   |            ^^^ not found in this scope

error[E0728]: `await` is only allowed inside `async` functions and blocks
  --> src\search\routes\common.rs:25:12
   |
4  |   pub fn authenticate() -> String {
   |          ------------ this is not `async`
...
25 |   let resz = client.post("https://api-crt.cert.havail.sabre.com/v2/auth/token")
   |  ____________^
26 | |     .headers(construct_headers())
27 | |     .body("grant_type=client_credentials")
28 | |     .json(&map)
29 | |     .send()
30 | |     .await?;
   | |__________^ only allowed inside `async` functions and blocks

error[E0277]: the trait bound `std::result::Result<search::routes::reqwest::Response, search::routes::reqwest::Error>: std::future::Future` is not satisfied
  --> src\search\routes\common.rs:25:12
   |
25 |   let resz = client.post("https://api-crt.cert.havail.sabre.com/v2/auth/token")
   |  ____________^
26 | |     .headers(construct_headers())
27 | |     .body("grant_type=client_credentials")
28 | |     .json(&map)
29 | |     .send()
30 | |     .await?;
   | |__________^ the trait `std::future::Future` is not implemented for `std::result::Result<search::routes::reqwest::Response, search::routes::reqwest::Error>`

error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `std::ops::Try`)
  --> src\search\routes\common.rs:25:12
   |
4  |  / pub fn authenticate() -> String {
5  |  |
6  |  |     let res = reqwest::get("http://api.github.com/users")
7  |  | .expect("Couldnt")
...   |
25 |  | let resz = client.post("https://api-crt.cert.havail.sabre.com/v2/auth/token")
   |  |____________^
26 | ||     .headers(construct_headers())
27 | ||     .body("grant_type=client_credentials")
28 | ||     .json(&map)
29 | ||     .send()
30 | ||     .await?;
   | ||___________^ cannot use the `?` operator in a function that returns `std::string::String`
31 |  |
32 |  | }
   |  |_- this function should return `Result` or `Option` to accept `?`
   |
   = help: the trait `std::ops::Try` is not implemented for `std::string::String`
   = note: required by `std::ops::Try::from_error`

error[E0308]: mismatched types
 --> src\search\routes\common.rs:4:26
  |
4 | pub fn authenticate() -> String {
  |        ------------      ^^^^^^ expected struct `std::string::String`, found `()`
  |        |
  |        implicitly returns `()` as its body has no tail or `return` expression

** Обновление снова.

extern crate reqwest;
use hyper::header::{Headers, Authorization, Basic, ContentType};

fn construct_headers() -> Headers {
    let mut headers = Headers::new();
    headers.set(
        Authorization(
            Basic {
                username: "HI:ABGTYH".to_owned(),
                password: Some("%8YHT".to_owned())
            }
        )
     );
    headers.set(ContentType::form_url_encoded());
    headers
}

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

let client = reqwest::Client::new();
let resz = client.post("https://api.test.com/auth/token")
    .headers(construct_headers())
    .body("grant_type=client_credentials")
    .json(&map)
    .send()
    .await?;

}

** Новая ошибка.

error[E0425]: cannot find value `map` in this scope
  --> src\search\routes\common.rs:24:12
   |
24 |     .json(&map)
   |            ^^^ not found in this scope

error[E0277]: the trait bound `impl std::future::Future: search::routes::serde::Serialize` is not satisfied
  --> src\search\routes.rs:24:29
   |
24 |     HttpResponse::Ok().json(set_token)
   |                             ^^^^^^^^^ the trait `search::routes::serde::Serialize` is not implemented for `impl std::future::Future`

error[E0308]: mismatched types
  --> src\search\routes\common.rs:22:14
   |
22 |     .headers(construct_headers())
   |              ^^^^^^^^^^^^^^^^^^^ expected struct `search::routes::reqwest::header::HeaderMap`, found struct `hyper::header::Headers`
   |
   = note: expected struct `search::routes::reqwest::header::HeaderMap`
              found struct `hyper::header::Headers`

error[E0599]: no method named `json` found for struct `search::routes::reqwest::RequestBuilder` in the current scope
  --> src\search\routes\common.rs:24:6
   |
24 |     .json(&map)
   |      ^^^^ method not found in `search::routes::reqwest::RequestBuilder`

error[E0308]: mismatched types
  --> src\search\routes\common.rs:18:63
   |
18 |   pub async fn authenticate() -> Result<String, reqwest::Error> {
   |  _______________________________________________________________^
19 | |
20 | | let client = reqwest::Client::new();
21 | | let resz = client.post("https://api.test.com/auth/token")
...  |
27 | |
28 | | }
   | |_^ expected enum `std::result::Result`, found `()`
   |
   = note:   expected enum `std::result::Result<std::string::String, search::routes::reqwest::Error>`
           found unit type `()`

1 Ответ

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

Могу я уточнить ваш вопрос? Как я понимаю, вы уже знаете, как использовать функции из другого файла. Вам нужно знать, как делать запросы API и передавать результат из запроса в виде ответа?

Во-первых, вам нужно создать fetch_test.rs с использованием, например, reqwest lib:

let client = reqwest::Client::new();
let res = client.post("http://httpbin.org/post")
    .json(&map)
    .send()
    .await?;

Результат на карте или передать его как есть.

Вернуть результат в rout.rs: HttpResponse::Ok().json(res)

I надеюсь, это поможет вам.

...