Rust: env_or_default macro

Created on 12 Mar 2018  路  6Comments  路  Source: rust-lang/rust

I find my self doing something like this quite often:

const VERSION: Option<&'static str> = option_env!("CARGO_PKG_VERSION");

fn main() {
    println!("{}", VERSION.unwrap_or("unknown version"));
}

I think it would be nice to have a env_or_default macro that defaults to a fallback string at compile time if the environment variable cannot be found. I'm thinking of something like

const VERSION: &str = env_or_default!("CARGO_PKG_VERSION", "unknown version");

I know the runtime cost isn't that high but if it can be done at compile time, it should be done.

A-const-fn A-macros C-feature-request T-libs

Most helpful comment

Agreed. We can't make unwrap_or a const fn just yet (needs https://github.com/rust-lang/rfcs/pull/2342) but once we can, we should and then this macro would be redundant and deprecated.

All 6 comments

Alternatively we could just make .unwrap_or() a const fn to allow it being used in the const constructor.

const VERSION: &str = option_env!("CARGO_PKG_VERSION").unwrap_or("unknown version");

Agreed. We can't make unwrap_or a const fn just yet (needs https://github.com/rust-lang/rfcs/pull/2342) but once we can, we should and then this macro would be redundant and deprecated.

I don't think it is uncommon to require different semantics than just a default for None. The majority of my env lookups usually treat the empty string as equivalent to an unset variable, because (a) they're easier to set in the shell, (b) an empty string is not a useful value for many types of things, such as integers, paths, or version numbers.

Having something like LIBXYZ_DIR= cargo build search the current directory is silly.

fn nonempty_env(name: &str) -> Option<String> {
    match env::var(name) {
        Ok("") | Err(env::VarError::NotPresent) => None,
        Err(e) => panic!("error looking up {}: {}", name, e),
        Ok(s) => Some(s),
    }
}

So for me, env_or_default! would still not be useful.

@hanna-kruppe now that https://github.com/rust-lang/rfcs/pull/2342 has been merged, can we make .unwrap_or const fn?

I think so.

Saw https://github.com/rust-lang/rust/pull/76330, but it was closed because destructors cannot run in const contexts just yet

Was this page helpful?
0 / 5 - 0 ratings