stackedconfig

Crates.iostackedconfig
lib.rsstackedconfig
version0.1.2
sourcesrc
created_at2018-01-09 03:12:13.87681
updated_at2018-01-19 04:31:01.738144
description!!! DO NOT USE !!! Treat multiple nested config objects as a single config object with precedence. !!! DO NOT USE !!!
homepagehttps://github.com/bheklilr/rust-stackedconfig
repositoryhttps://github.com/bheklilr/rust-stackedconfig
max_upload_size
id46052
size667,914
Aaron Stevens (bheklilr)

documentation

https://bheklilr.github.io/rust-stackedconfig/stackedconfig/

README

rust-stackedconfig

Treat multiple nested config objects (e.g. JSON or YAML files) as a single config object with precedence.

Why should I use this library?

You shouldn't, it isn't anywhere near done yet and I'm definitely not the best at keeping up with side projects. This software is pre-alpha.

Why does this library exist?

This is a fun, small side-project for me to learn rust better, but my goal is for it to be good enough eventually for someone else to use seriously.

But why I want to use it?

Have you ever had the situation where your application had complex configuration? Something like this contrived example?

notifications:
    email:
        address: user@example.com
        on_new_post: false
        on_new_message: true
appearance:
    theme: dark
    font:
        family: Arial
        size: 14pt
web:
    proxy:
        http: http://proxy.com
        https: https://proxy.com
    ssl_verify: true
    trusted_hosts:
        - crates.io
        - rust-lang.org
credentials:
    username: null
    token: null

And you wanted to have multiple config files, such as on the system level in $APPDIR/app_config.yaml, on the user level at $HOME/app_config.yaml, and on the project level at $PROJECTDIR/app_config.yaml. Managing multiple config files with fallback is a pain. This library aims to make it easy to work with:

extern crate serde_json;
extern crate stackedconfig;

use serde_json::{Value, from_str};
use stackedconfig::{ConfigStack};

fn main() {
    // Normally would load these from disk
    let system_conf: Value = from_str(r#"
        {
            "notifications": {
                "email": {
                    "on_new_post": true,
                    "on_new_message": true
                }
            },
            "appearance":{
                "theme": "light",
                "font": {
                    "family": "Arial",
                    "size": "14pt"
                }
            }
            "web": {
                "proxy": {
                    "http": "http://proxy.com",
                    "https": "https://proxy.com"
                },
                "ssl_verify": true,
                "trusted_hosts": []
            },
            "credentials": {
                "username": null,
                "token": null
            }
        }
    "#)?;
    let user_conf: Value = from_str(r#"
        {
            "notifications": {
                "email": {
                    "address": "user@example.com"
                }
            },
            "appearance": {
                "theme": "dark"
            },
            "web": {
                "trusted_hosts": ["crates.io", "rust-lang.org"]
            },
            "credentials": {
                "username": "bheklilr",
                "token": "123456abcdef"
            }
        }
    "#)?;
    let stack = ConfigStack::new()
        .stack(system_conf)
        .stack(user_conf);
    // Nested access is available, separator can be customized to any character
    // with the `with_sep` method.
    println!("{}", stack.get("notifications/email/address")?.unwrap());
    // Calls to `get` return a `ConfigStack`, so sub-sections could be passed to
    // the relevant parts of your application
    println!("{}", stack.get("appearance")?.get("theme")?.unwrap());
    // The last config stacked takes precedence when doing lookups.
    // Values can be unwrapped from the stack for actual use later.
    println!("{}", stack.get("web/proxy/http")?.unwrap());
}

Limitations

Currently right now it only supports serde_json. My plan is to add serde_yaml and maybe some other formats as this project grows.

License

I put it under MIT, but honestly I really don't care what anyone does with this code. It is provided as-is. If you find a bug, feel free to submit an issue, or even better submit a PR fixing it.

Commit count: 30

cargo fmt