Skip to content
/ envy Public

envy: Deserialize environment variables into type-safe structs

License

MIT and 2 other licenses found

Licenses found

MIT
LICENSE
MIT
LICENSE.json
BSL-1.0
LICENSE.visit_struct
Notifications You must be signed in to change notification settings

p-ranav/envy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

fdb0dd3 · Aug 10, 2020

History

53 Commits
Aug 10, 2020
Aug 10, 2020
Aug 10, 2020
Aug 10, 2020
Aug 10, 2020
Aug 10, 2020
Aug 10, 2020
Aug 10, 2020
Aug 10, 2020
Aug 10, 2020
Aug 10, 2020
Aug 10, 2020
Aug 10, 2020

standard license version

envy is a small header-only library to deserialize environment variables into type-safe structs.

Quick Start

Start by creating a struct where to store the values of environment variables.

#include <envy/envy.hpp>

struct ServerConfig {
  int  server_alive_interval = 45;
  bool compression           = false;
  int  compression_level     = 0;
  bool forward_x11           = true;
};
ENVY_STRUCT(ServerConfig, server_alive_interval, compression, compression_level, forward_x11);

For each field in the struct, envy will look for an environment variable with the same name in upper case, e.g., for the field named forward_x11, envy will look for an environment variable named FORWARD_X11.

Use envy::get<T>() to get a deserialized, type-safe struct.

int main() {
  auto config = envy::get<ServerConfig>();
  
  std::cout << "Server Alive Interval : " << config.server_alive_interval << "\n";
  std::cout << "Compression Enabled?  : " << std::boolalpha << config.compression << "\n";
  std::cout << "Compression Level     : " << config.compression_level << "\n";
  std::cout << "Forward X11?          : " << std::boolalpha << config.forward_x11 << "\n"; 
}

Here's the stdout of the above program:

▶ ./main
Server Alive Interval : 45
Compression Enabled?  : false
Compression Level     : 0
Forward X11?          : true

▶ SERVER_ALIVE_INTERVAL=90 COMPRESSION=1 COMPRESSION_LEVEL=9 FORWARD_X11=0 ./main
Server Alive Interval : 90
Compression Enabled?  : true
Compression Level     : 9
Forward X11?          : false

Deserialize comma-separated values

Comma-separated values can be deserialized into an std::vector:

#include <envy/envy.hpp>

struct Config {
  std::vector<int> values;
};
ENVY_STRUCT(Config, values);

int main() {
  auto config = envy::get<Config>();

  for (auto& v : config.values) {
    std::cout << v << " ";
  }
}
▶ ./main

▶ VALUES=1,2,3,4,5 ./main
1 2 3 4 5

Deserialize JSON

JSON can be deserialized into std::map, std::unordered_map or even nlohmann::json:

#include <envy/envy.hpp>

struct Config {
  std::map<std::string, int> values;
};
ENVY_STRUCT(Config, values);

int main() {
  auto config = envy::get<Config>();

  for (auto& kv : config.values) {
    std::cout << kv.first << " : " << kv.second << "\n";
  }
}
▶ ./main

▶ VALUES='{"a": 1, "b": 2, "c": 3}' ./main
a : 1
b : 2
c : 3

Application Prefix for Environment Variables

#include <envy/envy.hpp>

struct Config {
  int   foo = 0;
  float bar = 0.0f;
  bool  baz = false;
};
ENVY_STRUCT(Config, foo, bar, baz);

int main() {
  auto config = envy::get<Config>("APP_"); // prefix for env vars

  std::cout << "foo : " << config.foo << "\n";
  std::cout << "bar : " << config.bar << "\n";
  std::cout << "baz : " << std::boolalpha << config.baz << "\n";
}
▶ ./main
foo : 0
bar : 0
baz : false

▶ APP_FOO=1 APP_BAR=3.14 APP_BAZ=1 ./main
foo : 1
bar : 3.14
baz : true

Generating Single Header

python3 utils/amalgamate/amalgamate.py -c single_include.json -s .

Contributing

Contributions are welcome, have a look at the CONTRIBUTING.md document for more information.

License

The project is available under the MIT license.