[TOOLS] 6 分鐘閱讀OraCore 編輯部

Rust CLI 天氣工具五步實作

這篇指南帶你用 Cargo、Clap、Tokio、Reqwest 和 Serde 做出可編譯、可測試的 Rust 命令列天氣工具。

分享 LinkedIn
Rust CLI 天氣工具五步實作

這篇教你用 Cargo、Clap、Tokio、Reqwest 和 Serde 做出一個可編譯、可測試的 Rust 命令列天氣工具。

這篇是寫給已經會另一種程式語言、想快速做出可用 Rust CLI 的開發者。你可以一路照著做,最後拿到一個能接收城市參數、發送非同步請求、輸出天氣資料,且可持續擴充的專案。

做完之後,你會得到一個標準 Cargo 專案、基本命令列介面、可運作的非同步網路呼叫,以及一套能直接延伸成正式工具的程式骨架。

開始之前

訂閱 AI 趨勢週報

每週精選模型發布、工具應用與深度分析,直送信箱。不定期,不騷擾。

不會寄垃圾信,隨時可取消。

  • 已安裝 Rust 工具鏈 1.95.0 stable,並透過 rustup 管理版本
  • Cargo 1.95.0、rust-analyzer、clippy、rustfmt 都已可用
  • 作業系統為 macOS、Linux 或 Windows 的 WSL2,且可使用 Unix-like shell
  • 編輯器為 VS Code 或 Neovim,並已啟用 rust-analyzer
  • 若天氣 API 需要驗證,請先準備好 API key
  • 依賴套件版本已確認:Tokio 1.40.0、Reqwest 0.12.7、Serde 1.0.210、Serde JSON 1.0.128、Clap 4.5.17、Anyhow 1.0.82

Step 1: 安裝 Rust 工具鏈

這一步的目的,是先把編譯器、套件管理器與格式化工具裝好,避免後面每一個步驟都卡在環境問題。你要先確認本機真的在用 stable 工具鏈,而不是系統預裝版本。

Rust CLI 天氣工具五步實作
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"
rustc --version
cargo --version
rustup component add rust-analyzer clippy rustfmt

驗收時,你應該看到 rustc 1.95.0 和 cargo 1.95.0,並且三個元件都能成功加入。這代表後續建立專案、檢查程式碼與自動格式化都已就緒。

Step 2: 建立 Cargo 專案

這一步的目的,是先產生一個標準的二進位 crate,讓你有乾淨的專案結構可以直接修改。Cargo 會同時建立原始碼目錄與建置設定,之後所有功能都會在這個骨架上展開。

Rust CLI 天氣工具五步實作
cargo new weather_cli
cd weather_cli
cargo run

驗收時,你應該看到預設的 Hello, world! 輸出,並且專案底下出現 target/debug/weather_cli。這代表 Cargo 已經能成功編譯並執行你的 CLI 程式。

Step 3: 加入命令列參數

這一步的目的,是讓程式不再只是固定輸出,而是能接收使用者傳入的城市名稱與選項。你會先把 Clap 接進來,建立一個可解析的參數結構,讓 CLI 真正具備互動性。

cargo add clap --features derive
cargo add anyhow

use clap::Parser;

#[derive(Parser, Debug)]
struct Args {
    #[arg(short, long)]
    city: String,
}

fn main() {
    let args = Args::parse();
    println!("City: {}", args.city);
}

驗收時,你應該看到執行 cargo run -- --city Tokyo 後,畫面輸出 City: Tokyo。這代表參數已經被正確解析,Clap 的整合也沒有問題。

Step 4: 串接非同步天氣請求

這一步的目的,是把 CLI 變成真的會對外溝通的工具。你要引入 Tokio、Reqwest 與 Serde,讓程式能在非同步 runtime 中送出 HTTP 請求,並準備解析回傳資料。

cargo add tokio --features full
cargo add reqwest --features json,rustls-tls
cargo add serde --features derive
cargo add serde_json

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let body = reqwest::get("https://example.com/weather.json").await?.text().await?;
    println!("{}", body);
    Ok(())
}

驗收時,你應該看到一段 HTTP 回應內容,或至少能成功印出 JSON 字串。這代表非同步執行緒、網路請求與錯誤回傳都已正常運作。

Step 5: 格式化、檢查並輸出正式版本

這一步的目的,是把專案整理成可以交付的狀態。你要用 fmt、clippy、test 與 release build,確認程式碼風格一致、沒有明顯警告,且可產出最佳化執行檔。

cargo fmt
cargo clippy
cargo test
cargo build --release

驗收時,你應該看到格式化完成、clippy 沒有錯誤、測試通過,並且在 target/release/weather_cli 找到正式版執行檔。這代表你的 CLI 已經具備可維護與可發佈的基本條件。

指標基準/優化前結果/優化後
專案狀態尚未建立 Rust 應用可執行的 CLI 二進位檔
執行模型同步占位程式Tokio 非同步 runtime
依賴覆蓋沒有外部套件Clap、Reqwest、Serde、Tokio
建置輸出只有除錯版最佳化 release 版

常見錯誤

  • 用系統套件管理器裝 Rust,結果版本太舊。修法:改用 rustup,或把 ~/.cargo/bin 放到 PATH 前面,確保呼叫到正確工具鏈。
  • 忘記在 cargo run 後加上 --,導致參數被 Cargo 吃掉。修法:改成 cargo run -- --city Tokyo,讓應用程式自己接收參數。
  • 把同步函式和非同步請求混在一起,卻沒有 Tokio runtime。修法:把入口函式改成 #[tokio::main] async fn main(),並把網路呼叫放進 async 區塊。

接下來可以看什麼

下一步可以把天氣資料改成真正的 API 回應模型,加入 thiserror 做錯誤分類,再補上整合測試與 crates.io 發佈流程,讓這個 CLI 變成可長期維護的正式工具。