MCPcopy Index your code
hub / github.com/LukasKalbertodt/confique

github.com/LukasKalbertodt/confique @v0.4.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.4.0 ↗ · + Follow
260 symbols 422 edges 36 files 55 documented · 21%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Confique: type-safe, layered configuration library

CI status of main Crates.io Version docs.rs

Confique is a rather light-weight library that helps with configuration management in a type-safe and DRY (don't repeat yourself) fashion.

Features:

  • Type safe: the code using the config values does not need to parse strings or unwrap any Options. All values already have the correct type.
  • Layered configuration: you can load from and then merge multiple sources of configuration.
  • Load config values from:
    • Environment variables
    • Files: TOML, YAML, and JSON5
    • Anything with a serde Deserializer
  • Based on serde: less code in confique (more light-weight) and access to a huge ecosystem of high quality parsers.
  • Easily generate configuration "templates": describe all available config values to your users without repeating yourself.
  • Simple validation: validity checks can easily be added via attributes.

Simple example

use std::{net::IpAddr, path::PathBuf};
use confique::Config;


#[derive(Config)]
struct Conf {
    /// Port to listen on.
    #[config(env = "PORT", default = 8080)]
    port: u16,

    /// Bind address.
    #[config(default = "127.0.0.1")]
    address: IpAddr,

    #[config(nested)]
    log: LogConf,
}

#[derive(Config)]
struct LogConf {
    #[config(default = true)]
    stdout: bool,

    #[config(validate(file.is_absolute(), "log file requires absolute path"))]
    file: Option<PathBuf>,

    #[config(default = ["debug"])]
    ignored_modules: Vec<String>,
}


let config = Conf::builder()
    .env()
    .file("example-app.toml")
    .file("/etc/example-app/config.toml")
    .load()?;

See the documentation for more information.

Configuration Template

With the above example, you can automatically generate a configuration template: a file in a chosen format that lists all values with their description, default values, and env values.

toml::template::<Conf>() yaml::template::<Conf>() json5::template::<Conf>()
# Port to listen on.
#
# Can also be specified via
# environment variable `PORT`.
#
# Default value: 8080
#port = 8080

# Bind address.
#
# Default value: "127.0.0.1"
#address = "127.0.0.1"

[log]
# <omitted>
# Port to listen on.
#
# Can also be specified via
# environment variable `PORT`.
#
# Default value: 8080
#port: 8080

# Bind address.
#
# Default value: 127.0.0.1
#address: 127.0.0.1

log:
  # <omitted>
{
  // Port to listen on.
  //
  // Can also be specified via
  // environment variable `PORT`.
  //
  // Default value: 8080
  //port: 8080,

  // Bind address.
  //
  // Default value: "127.0.0.1"
  //address: "127.0.0.1",

  log: {
    // <omitted>
  },
}

(Note: The "environment variable" sentence is on a single line; I just split it into two lines for readability in this README.)

Comparison with other libraries/solutions

config

  • Loosely typed:
    • You access configuration values via string path (e.g. "http.port") and deserialize at "use site".
    • No defined schema
  • More features
  • Larger library
  • If you need a "config template", you need to repeat code/docs

figment

  • Also based on serde and also uses your own structs as data store, thus type safe
  • Instead of using layer types, aggregates different layers in a dynamic data store
  • If you need a "config template", you need to repeat code/docs

Just serde?

Serde is not a configuration, but a deserialization library. But you can get surprisingly far with just serde and it might actually be sufficient for your project. However, once you want to load from multiple sources, you either have make all your fields Option or repeat code/docs. With confique you also get some other handy helpers.

Status of this project

There is still some design space to explore and there are certainly still many features one could add. However, the core interface (the derive macro and the core traits) probably won't change a lot anymore. Confique is used by a web project (that's already used in production) which I'm developing alongside of confique.


License

Licensed under either of Apache License, Version 2.0 or MIT license at your option. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Extension points exported contracts — how you extend this code

Formatter (Interface)
Trait abstracting over the format differences when it comes to formatting a configuration template. To implement this y [3 …
src/template.rs
Config (Interface)
A configuration object that can be deserialized in layers via `serde`. You would usually derive this trait for your own
src/lib.rs
Layer (Interface)
A configuration layer: all fields are optional. Can be directly deserialized via `serde`.
src/lib.rs

Core symbols most depended-on inside this repo

assert_err_contains
called by 38
tests/validation.rs
from_env
called by 21
src/internal.rs
comment
called by 8
src/yaml.rs
load
called by 7
src/file.rs
parse_eq_value
called by 6
macro/src/parse.rs
parse
called by 5
macro/src/parse.rs
buffer
called by 4
src/yaml.rs
make_gap
called by 4
src/template.rs

Shape

Function 97
Method 82
Class 60
Enum 18
Interface 3

Languages

Rust100%

Modules by API surface

src/toml.rs22 symbols
src/json5.rs21 symbols
src/yaml.rs19 symbols
tests/validation.rs16 symbols
macro/src/parse.rs16 symbols
src/meta.rs13 symbols
tests/general.rs12 symbols
src/template.rs12 symbols
macro/src/ir.rs11 symbols
src/internal.rs10 symbols
src/env/mod.rs9 symbols
macro/src/gen/mod.rs8 symbols

For agents

$ claude mcp add confique \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact