Rust を使用して天気予報コマンド ライン ツールを最初から実装する

この記事では、Rust を使用して、都市名を入力して地域の天気を取得するコマンドライン ツールを実装します。

この記事は公式アカウント「Frontend of Puff Science」にも含まれており、記事は継続的に更新されます。

目標

ここでは Windows に実装するので、最終的な効果は次のようになります。

北京の天気を取得するためのコマンドライン入力:

weather beijing

出力:

-----正在获取天气信息, 请稍后...-----
  当前温度:297.09℃ 
  当前最低温:297.09℃ 
  当前最高温:297.09℃
  体感温度:295.7℃
  湿度:6%
  今日日出时间:04:55:54
  今日日落时间:19:26:10
  所在经度:116.3972
  所在纬度:39.9075

インターフェース

ここでは無料の、アカウントを登録して、ここにアクセスして API KEY を申請します。

呼び出し方法:

https://api.openweathermap.org/data/2.5/weather?q={city name}&appid={API key}

例えば:

https://api.openweathermap.org/data/2.5/weather?q=beijing&appid=xxx

ディレクトリ構造

今回のディレクトリ構造は比較的単純で、main.rs がエントリコードを記述し、handler がメインロジックを記述します。

weather
├── Cargo.lock
├── Cargo.toml
├── README.md
├── src
│   ├── handler
│   │   └── mod.rs
│   └── main.rs

依存関係をインストールする

[package]
edition = "2021"
name = "weather"
version = "0.1.0"[dependencies]
chrono = "0.4.19" # 时间格式化工具
colored = "2.0.0" # 控制台上色
exitfailure = "0.5.1" # 错误处理
reqwest = {version = "0.11", features = ["json"]} # 发送网络请求
serde = "1.0.114" 
serde_derive = "1.0.114" 
serde_json = "1.0.56" 
structopt = "0.3.21" # 解析命令行参数
tokio = {version = "1", features = ["full"]}

次に依存関係をインストールし、実行しますcargo install

コーディングを開始する

上記の準備が完了したら、アプリケーションの作成を開始できます。src/main.rs

mod handler;
use handler::{print_response, Weather};
​
use exitfailure::ExitFailure;
use structopt::StructOpt;
​
#[derive(StructOpt, Debug)]
pub struct Input {
    pub city: String,
}
​
#[tokio::main]
async fn main() -> Result<(), ExitFailure> {
    // 获取命令行输入的参数,第一个参数即是 city name
    let input = Input::from_args();
    match Weather::get(&input.city).await {
        Ok(r) => print_response(&r),
        Err(e) => println!("请求出错,{:?}", &e),
    };
​
    Ok(())
}

src/handler/mod.rsメインロジックを書く

use chrono::prelude::*;
use colored::*;
use std::time::{Duration, UNIX_EPOCH};
​
use exitfailure::ExitFailure;
use reqwest::Url;
use serde_derive::{Deserialize, Serialize};
​
/// 定义接口返回的数据结构
#[derive(Deserialize, Serialize, Debug)]
pub struct Weather {
    main: Temperature,
    sys: Sys,
    coord: Coord,
}
​
#[derive(Serialize, Deserialize, Debug)]
pub struct Temperature {
    temp: f64,
    temp_min: f64,
    temp_max: f64,
    feels_like: f64,
    humidity: f64,
}
​
#[derive(Deserialize, Serialize, Debug)]
pub struct Coord {
    lon: f64,
    lat: f64,
}
​
#[derive(Serialize, Deserialize, Debug)]
pub struct Sys {
    sunrise: i32,
    sunset: i32,
}
​
/// 定义天气接口的实现
impl Weather {
    pub async fn get(city: &String) -> Result<Self, ExitFailure> {
        println!("{}", "-----正在获取天气信息, 请稍后...-----".bright_green());
        let url = format!("http://api.openweathermap.org/data/2.5/weather?q={}&APPID=自己去申请一下
      ", city);
        let url = Url::parse(url.as_str())?;
        let response = reqwest::get(url).await?.json::<Weather>().await?;
​
        Ok(response)
    }
}
​
/// 格式化时间,将时间戳转成指定格式
pub fn formate_timestamp(timestamp: i32, format: &str) -> String {
    let time = UNIX_EPOCH + Duration::from_secs(timestamp as u64);
    let datetime = DateTime::<Local>::from(time);
    datetime.format(format).to_string()
}
​
/// 打印返回结果到控制台
pub fn print_response(resp: &Weather) {
    println!(
        "  当前温度:{}℃ \n  当前最低温:{}℃ \n  当前最高温:{}℃ \n  体感温度:{}℃ \n  湿度:{}% \n  今日日出时间:{} \n  今日日落时间:{} \n  所在经度:{} \n  所在纬度:{}",
        resp.main.temp.to_string().bright_red(),
        resp.main.temp_min,
        resp.main.temp_max,
        resp.main.feels_like,
        resp.main.humidity,
        formate_timestamp(resp.sys.sunrise, "%H:%M:%S"),
        formate_timestamp(resp.sys.sunset, "%H:%M:%S"),
        resp.coord.lon,
        resp.coord.lat
    );
}
​
/// 时间戳的单测
#[test]
fn test_timestamp_to_time() {
    assert_eq!(
        formate_timestamp(1643467428, "%H:%M:%S"),
        "22:43:48".to_string()
    );
​
    assert_eq!(
        formate_timestamp(1643467428, "%Y-%m-%d %H:%M:%S"),
        "2022-01-29 22:43:48".to_string()
    )
}

パッケージングと構成

最後に、コードを記述した後、それをパッケージ化する必要があります。これにより、コンソールが実行されます。

cargo build --release

パッケージ化が完了すると、target/release/weather.exeファイルが

次に、このファイルを環境変数で設定します。

画像.png最後に、システム内の任意の場所でコンソールを開いて、現在の天気を確認できます。

画像.png

終わり~~

パブリック アカウント「Frontend of Puff Science」にご注目いただき、記事の更新を続けていただければ幸いです...

おすすめ

転載: juejin.im/post/7235283785260302392