easyenv/
lib.rs

1// Copyright (c) 2020 Brandon Thomas <bt@brand.io>
2
3//! Very simple helper functions for environment variables and environment variable-driven
4//! `env_logger` configuration.
5
6#![deny(dead_code)]
7#![deny(missing_docs)]
8#![deny(unreachable_patterns)]
9#![deny(unused_extern_crates)]
10#![deny(unused_imports)]
11#![deny(unused_qualifications)]
12#![deny(unused_qualifications)]
13
14use env_logger;
15use std::error::Error;
16use std::fmt::{Display, Debug, Formatter};
17use std::{env, fmt};
18
19mod boolean;
20mod duration;
21mod pathbuf;
22mod string;
23mod num;
24
25/// Name of the environment variable Rust's env logger uses
26pub const ENV_RUST_LOG : &'static str = "RUST_LOG";
27
28const DEFAULT_LOG_LEVEL: &'static str = "info";
29
30/// Errors with env variables.
31#[derive(Debug)]
32pub enum EnvError {
33  /// The environment variable value is not unicode.
34  NotUnicode,
35  /// Problem parsing the env variable as the desired type.
36  ParseError {
37    /// Explanation of the parsing failure.
38    reason: String
39  },
40  /// The required environment variable wasn't present.
41  RequiredNotPresent,
42}
43
44impl Display for EnvError {
45  fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
46    write!(f, "EnvError::ParseError")
47  }
48}
49
50impl Error for EnvError {
51  fn source(&self) -> Option<&(dyn Error + 'static)> {
52    None
53  }
54}
55
56pub use boolean::get_env_bool_optional;
57pub use boolean::get_env_bool_or_default;
58pub use boolean::get_env_bool_required;
59
60pub use duration::get_env_duration_seconds_optional;
61pub use duration::get_env_duration_seconds_or_default;
62pub use duration::get_env_duration_seconds_required;
63
64pub use num::get_env_num;
65
66pub use pathbuf::get_env_pathbuf_optional;
67pub use pathbuf::get_env_pathbuf_or_default;
68pub use pathbuf::get_env_pathbuf_required;
69
70pub use string::get_env_string_optional;
71pub use string::get_env_string_or_default;
72pub use string::get_env_string_required;
73
74/// Initialize Rust's env logger.
75///
76/// The Rust logger reads the desired log level from the `RUST_LOG` environment variable. If this
77/// isn't set, the provided default is used. If a default fallback isn't provided to this function,
78/// we fall back to `"info"`.
79///
80/// A more robust logging config might configure on a per-component basis, eg.
81/// `"tokio_reactor=warn,hyper=info,debug"`. You can read more in the `log` and `env_logger` crate
82/// docs.
83pub fn init_env_logger(default_if_absent: Option<&str>) {
84  if env::var(ENV_RUST_LOG)
85    .as_ref()
86    .ok()
87    .is_none()
88  {
89    let default_log_level = default_if_absent.unwrap_or(DEFAULT_LOG_LEVEL);
90    println!("Setting default logging level to \"{}\", override with env var {}.",
91             default_log_level, ENV_RUST_LOG);
92    env::set_var(ENV_RUST_LOG, default_log_level);
93  }
94
95  env_logger::init();
96}
97
98/// Initialize dotenv with the default `.env` config file.
99pub fn init_dotenv() {
100  match dotenv::dotenv() {
101    Ok(_) => println!("dotenv configs initialized"),
102    Err(e) => println!("Could not initialize dotenv: {:?}", e),
103  }
104}
105
106/// Initialize dotenv and env logger.
107/// See `init_dotenv()` and `init_env_logger(Option<&str>)` for further details.
108pub fn init_all_with_default_logging(default_if_absent: Option<&str>) {
109  init_dotenv();
110  init_env_logger(default_if_absent)
111}