Skip to main content

Crate libconfig

Crate libconfig 

Source
Expand description

Serde serialization and deserialization for libconfig format

This crate provides support for serializing and deserializing Rust data structures to and from the libconfig configuration file format.

libconfigasaurus logo

§serde-libconfigasaurus

A Rust serde implementation for the libconfig configuration format.

§Supported Types

All libconfig value types are supported:

libconfig typeRust / Value type
booleanbool / Value::Bool
integeri32 / Value::Integer
integer64i64 / Value::Integer64
floatf64 / Value::Float
stringString / Value::String
array [...]Vec<T> / Value::Array (homogeneous scalars)
list (...)tuples / Value::List (heterogeneous values)
group {...}structs / Value::Group (named settings)

Integer literals support decimal, hex (0xFF), binary (0b1010), and octal (0o17 / 0q17) formats. Values exceeding the 32-bit range are automatically promoted to 64-bit, or use the L suffix explicitly (100L).

§Quick Start

[dependencies]
serde-libconfigasaurus = "0.3.2"
serde = { version = "1.0", features = ["derive"] }

§Typed Deserialization

use serde::Deserialize;
use libconfig::from_str;

#[derive(Debug, Deserialize)]
struct Server {
    hostname: String,
    port: i32,
    ssl: bool,
}

let config = r#"
    hostname = "localhost";
    port = 8080;
    ssl = true;
"#;

let server: Server = from_str(config).unwrap();

§Serialization

use serde::Serialize;
use libconfig::to_string;

#[derive(Serialize)]
struct AppSettings {
    name: String,
    version: i32,
}

let settings = AppSettings {
    name: "My App".to_string(),
    version: 1,
};

// The serde serializer always wraps the top-level struct in { }.
// For braces-free output, use Config::new() + set() + Config::to_string().
let output = to_string(&settings).unwrap();
// {
//   name = "My App";
//   version = 1;
// }

§Dynamic Config

When you don’t know the structure at compile time, use Config for dynamic access:

use libconfig::Config;

let cfg = Config::from_str(r#"
    title = "My HTTP server";
    listen_ports = [80, 443];
    misc = {
        owner = "Chuck Norris";
        contact = {
            phone = "415-256-9999";
            emails = ["chuck@norris.com", "chuck.norris@gmail.com"];
        };
    };
"#).unwrap();

// Index with dotted paths
assert_eq!(cfg["title"].as_str(), Some("My HTTP server"));
assert_eq!(cfg["listen_ports.0"].as_i32(), Some(80));
assert_eq!(cfg["misc.contact.phone"].as_str(), Some("415-256-9999"));

§Reading from a File

use libconfig::Config;

let cfg = Config::from_file("settings.cfg").unwrap();
println!("{}", cfg["database.host"]);

§Setting Paths

Values can be read, written, and removed using libconfig-style dotted paths. Array and list elements are addressed with bracket notation ([index]) or bare numeric segments:

use libconfig::{Config, Value};

let mut cfg = Config::from_str(r#"ports = [80, 443];"#).unwrap();

// Read
assert_eq!(cfg.lookup("ports.[0]").unwrap().as_i32(), Some(80));
assert_eq!(cfg.lookup("ports.0").unwrap().as_i32(), Some(80)); // bare numeric also works

// Write (set existing)
cfg.set("ports.[0]", Value::Integer(8080));
assert_eq!(cfg["ports.[0]"], 8080);

// Write (auto-creates intermediate groups)
cfg.set("database.credentials.username", Value::String("admin".to_string()));
assert_eq!(cfg["database.credentials.username"], "admin");

// Remove (returns the removed value)
let mut cfg = Config::from_str(r#"a = 1; b = 2; c = 3;"#).unwrap();
let removed = cfg.remove("b");
assert_eq!(removed, Some(Value::Integer(2)));
assert!(cfg.lookup("b").is_none());

// Remove array element (subsequent elements shift down)
let mut cfg = Config::from_str(r#"items = [10, 20, 30];"#).unwrap();
cfg.remove("items.[0]");
assert_eq!(cfg["items.[0]"], 20);

§Format Features

  • Top-level implicit groups (no outer braces required)
  • Case-insensitive booleans (true, True, TRUE, FaLsE)
  • Adjacent string concatenation ("hello" " world" -> "hello world")
  • Comments: #, //, /* */
  • Setting separators: semicolons, commas, or whitespace (all optional)
  • Both = and : as key-value delimiters

§Examples

cargo run --example basic       # Typed serialization/deserialization round-trip
cargo run --example config      # Dynamic Config type: get/set all libconfig types
cargo run --example streaming   # Tokio TCP stream of libconfig packets

§License

MIT OR Apache-2.0

§Further Reading

Re-exports§

pub use de::Deserializer;
pub use de::from_str;
pub use error::Error;
pub use error::Result;
pub use ser::Serializer;
pub use ser::to_string;
pub use value::Config;
pub use value::Map;
pub use value::Value;
pub use value::from_value;

Modules§

config_api
Top-level document wrapper for reading and writing libconfig data.
de
Deserializer for libconfig format
error
Error types for libconfig serialization and deserialization
ser
Serializer for libconfig format
value
A dynamically-typed representation of libconfig data
value_api
Dynamically-typed value type for libconfig data.