🦍

clapで手軽に環境変数を扱う

はじめに

Rustでは環境変数を扱いたい場合はdotenvが有名と思いますが、残念ながらdotenvはメンテされていません。
また、次の記事ではdotenvyが紹介されていたが、こちらも現在は残念ながらほとんどメンテされていない状況でした。

https://zenn.dev/fraternite/articles/d596381b76fe3c

そこでdotenvのかわりとまではいかがないがclapを使って手軽に環境変数を扱えるので軽く紹介します。
.envを読み取る機能はないですが、手軽に構造体にデシリアライズしたい場合は便利ではないかなと思います。

環境

次の環境で動作確認しています。

$ uname -a
Darwin gorilla.local 23.1.0 Darwin Kernel Version 23.1.0: Mon Oct  9 21:27:24 PDT 2023; root:xnu-10002.41.9~6/RELEASE_ARM64_T6000 arm64

$ cargo --version
cargo 1.73.0 (9c4383fb5 2023-08-26)

やり方

とても簡単で、まずfeaturesderiveenvをつけます。

Cargo.toml
[dependencies]
clap = { version = "4.4.11", features = ["derive", "env"] }

あとは#[arg(env)]をつけるだけです。

use clap::Parser;

#[derive(Debug, Parser)]
pub struct Config {
    #[arg(long, env, hide_env_values = true)]
    pub host: String,
    #[arg(long, env, hide_env_values = true)]
    pub port: u16,
}

fn main() {
    let config = Config::parse();
    dbg!(config);
}

これを実行してみると、環境変数が構造体にデシリアライズされていることを確認できます。

$ PORT=8080 HOST=localhost cargo run       
   Compiling rust-clap-env v0.1.0 (/Users/skanehira/dev/github.com/skanehira/rust-clap-env)
    Finished dev [unoptimized + debuginfo] target(s) in 0.63s
     Running `target/debug/rust-clap-env`
[src/main.rs:13] config = Config {
    host: "localhost",
    port: 8080,
}

当たり前ですが、clapはコマンドラインパーサーなので、引数も指定できます。

$ cargo run -- --host localhost --port 8080        
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/rust-clap-env --host localhost --port 8080`
[src/main.rs:13] config = Config {
    host: "localhost",
    port: 8080,
}

また、環境変数と引数を同時に指定した場合は引数が優先されます。

$ PORT=8080 HOST=localhost cargo run -- --port 3333
    Finished dev [unoptimized + debuginfo] target(s) in 0.01s
     Running `target/debug/rust-clap-env --port 3333`
[src/main.rs:13] config = Config {
    host: "localhost",
    port: 3333,
}

さいごに

簡単ではありますが、clapを使って環境変数を扱うやり方について紹介しました。
最近ではウェブアプリケーションは大体コンテナ化されていて、環境変数は設定された状態で起動するので、clapがちょうどよいかもしれません。
よかったら使ってみてください。

FRAIMテックブログ

Discussion