rs_envflag

This crate provides an easy to define flags controlled by environment variables. It is a rust, and of course much more rustacean, reimplementation of https://github.com/TimeExceed/envflag.

a str flag without default values

Here is an example about defining a str flag.

```rust use rsenvflagmacros::*;

/// an example about str flag

[envflag]

const STR_FLAG: Option;

fn main() { if let Some(x) = STR_FLAG.fetch() { println!("{}", x); } else { println!("not present."); } } ```

When we run it directly, STR_FLAG will be None.

text $ cargo build --examples && target/debug/examples/str not present.

But once STR_FLAG is set, it looks like

text $ cargo build --examples && STR_FLAG=abc target/debug/examples/str abc

a str flag with default values

Also we can define default values to flags.

```rust use rsenvflagmacros::*;

/// an example about str flag with default

[envflag(default="abc")]

const STRFLAGW_DEFAULT: String;

fn main() { println!("{}", STRFLAGW_DEFAULT.fetch()); } ```

Then we will compile and run it.

text $ cargo build --examples && target/debug/examples/str && STR_FLAG_W_DEFAULT=xyz target/debug/examples/str xyz

i64/f64/bool flags with/without default values

We can also define i64, f64 and bool flags, either with or without, default values. Please refer to examples/ for details.

customized types and customized parsers

Now we will show how to define flags with customized types.

```rust use rsenvflagmacros::*;

[envflag(parser=v_parser)]

const X: Option;

fn main() { if let Some(x) = X.fetch() { println!("{:?}", x); } else { println!("not present."); } }

[derive(Debug)]

struct V(String);

fn vparser(key: &str, value: &str) -> V { V(value.to_string()) } ```

To define default values of env flags of customized types, more things are required.

```rust use rsenvflagmacros::*;

[envflag(parser=v_parser, default=&V::DEFAULT)]

const XWDEFAULT: V;

fn main() { println!("{:?}", XWDEFAULT.fetch()); }

[derive(Debug)]

struct V(String);

impl V { const DEFAULT: V = V(String::new()); }

fn vparser(key: &str, value: &str) -> V { V(value.to_string()) }

impl From<&V> for V { fn from(value: &V) -> Self { V(value.0.clone()) } } ```

  1. Besides parsers, const default values are required. And they must be refered by references, e.g., in this example default=&V::DEFAULT.
  2. A conversion from &V to V. Why so bothering? The answer is that the default values can have different types. Just they, actually their references, must be convertiable to types of flags.

flag renaming

Names of env variables and those in rust can be different. We support it by env_name attribute.

```rust use rsenvflagmacros::*;

/// env is named as XYZ rather ABC.

[envflag(env_name="XYZ")]

const ABC: Option;

fn main() { if let Some(x) = ABC.fetch() { println!("{}", x); } else { println!("not present."); } } ```

Now, this program will response what env variable XYZ is.

text $ cargo build --examples && target/debug/examples/env_rename && XYZ=xyz target/debug/examples/env_rename not present. xyz

crate renaming

Occasionally, crate rs_envflag have to be imported as a different name. We also support this case by crate attribute. Please refer to examples/crate_rename.rs for details.