use libconfig::{Config, Value};
fn main() {
let input = r#"
# A top-level implicit group (no outer braces)
name = "My Application";
version = 1;
version_long = 100000000000L;
pi = 3.14159;
enabled = true;
# Integer literal formats: hex, binary, octal (all auto-promote to i64 if needed)
hex_port = 0x1F90; # = 8080 decimal
bin_flag = 0b1010; # = 10 decimal
oct_val = 0o17; # = 15 decimal
# An array: homogeneous scalar values in [ ]
ports = [80, 443, 8080];
# A list: heterogeneous values in ( ), can nest aggregates
misc = ("text", 42, true, 3.14, [1, 2], ("nested", "list"));
# A group: named settings in { }
database = {
host = "localhost";
port = 5432;
credentials = {
username = "admin";
password = "secret";
};
};
"#;
let mut cfg = Config::from_str(input).expect("Failed to parse config");
println!("=== Boolean ===");
let enabled: bool = cfg["enabled"].as_bool().unwrap();
println!(" get: enabled = {}", enabled);
println!("\n=== Integer (i32) ===");
let version: i32 = cfg["version"].as_i32().unwrap();
println!(" get: version = {}", version);
println!("\n=== Integer64 (i64) ===");
let version_long: i64 = cfg["version_long"].as_i64().unwrap();
println!(" get: version_long = {}", version_long);
println!("\n=== Float (f64) ===");
let pi: f64 = cfg["pi"].as_f64().unwrap();
println!(" get: pi = {}", pi);
println!("\n=== String ===");
let name: &str = cfg["name"].as_str().unwrap();
println!(" get: name = {}", name);
println!("\n=== Array ===");
let ports = cfg["ports"].as_array().unwrap();
println!(" get: ports = {:?}", ports);
println!(" get: ports[0] = {}", cfg["ports.0"].as_i32().unwrap());
println!("\n=== List ===");
let misc = cfg["misc"].as_array().unwrap(); println!(" get: misc has {} elements", misc.len());
println!(" get: misc[0] = {}", misc[0].as_str().unwrap());
println!(" get: misc[1] = {}", misc[1].as_i32().unwrap());
println!(" get: misc[2] = {}", misc[2].as_bool().unwrap());
println!(" get: misc[3] = {}", misc[3].as_f64().unwrap());
println!(" get: misc[4] is array = {}", misc[4].is_array());
println!(" get: misc[5] is list = {}", misc[5].is_list());
println!("\n=== Group ===");
let db_group = cfg["database"].as_group().unwrap();
println!(
" get: database has {} keys: {:?}",
db_group.len(),
db_group.keys().collect::<Vec<_>>()
);
println!(
" get: database.host = {}",
cfg["database.host"].as_str().unwrap()
);
println!(
" get: database.port = {}",
cfg["database.port"].as_i32().unwrap()
);
println!("\n=== Integer Literal Formats ===");
println!(" hex 0x1F90 = {}", cfg["hex_port"].as_i32().unwrap()); println!(" bin 0b1010 = {}", cfg["bin_flag"].as_i32().unwrap()); println!(" oct 0o17 = {}", cfg["oct_val"].as_i32().unwrap());
println!("\n=== Dotted Path Lookup ===");
println!(
" lookup: database.credentials.username = {}",
cfg.lookup("database.credentials.username")
.unwrap()
.as_str()
.unwrap()
);
println!(
" lookup: ports.2 = {}",
cfg.lookup("ports.2").unwrap().as_i32().unwrap()
);
println!(
" lookup: misc.5.0 = {}",
cfg.lookup("misc.5.0").unwrap().as_str().unwrap()
);
println!(" lookup: nonexistent = {:?}", cfg.lookup("nonexistent"));
println!("\n\n=== Setting Values ===");
*cfg.lookup_mut("enabled").unwrap() = Value::Bool(false);
println!(" set: enabled = {}", cfg["enabled"]);
*cfg.lookup_mut("version").unwrap() = Value::Integer(2);
println!(" set: version = {}", cfg["version"]);
*cfg.lookup_mut("version_long").unwrap() = Value::Integer64(200000000000);
println!(" set: version_long = {}", cfg["version_long"]);
*cfg.lookup_mut("pi").unwrap() = Value::Float(3.14);
println!(" set: pi = {}", cfg["pi"]);
*cfg.lookup_mut("name").unwrap() = Value::String("Updated App".to_string());
println!(" set: name = {}", cfg["name"]);
*cfg.lookup_mut("ports.0").unwrap() = Value::Integer(9090);
println!(" set: ports[0] = {}", cfg["ports.0"]);
cfg.set("ports", Value::Array(vec![Value::Integer(8080), Value::Integer(8443)]));
println!(" set: ports = {:?}", cfg["ports"].as_array().unwrap());
*cfg.lookup_mut("misc.0").unwrap() = Value::String("updated".to_string());
println!(" set: misc[0] = {}", cfg["misc.0"]);
cfg.set("misc", Value::List(vec![
Value::String("mixed".to_string()),
Value::Integer(99),
Value::Bool(false),
]));
println!(" set: misc = {}", cfg["misc"]);
*cfg.lookup_mut("database.host").unwrap() = Value::String("10.0.0.1".to_string());
println!(" set: database.host = {}", cfg["database.host"]);
*cfg.lookup_mut("database.credentials.password").unwrap() =
Value::String("new_secret".to_string());
println!(
" set: database.credentials.password = {}",
cfg["database.credentials.password"]
);
cfg.set("cache.redis.host", Value::String("127.0.0.1".to_string()));
cfg.set("cache.redis.port", Value::Integer(6379));
println!(" set: cache.redis.host = {}", cfg["cache.redis.host"]);
println!(" set: cache.redis.port = {}", cfg["cache.redis.port"]);
println!("\n\n=== Removing Values ===");
let removed = cfg.remove("enabled");
println!(" remove: 'enabled' returned {:?}", removed);
println!(" remove: lookup 'enabled' after = {:?}", cfg.lookup("enabled"));
cfg.remove("database.credentials.password");
println!(" remove: 'database.credentials.password' gone = {}", cfg.lookup("database.credentials.password").is_none());
cfg.remove("ports.[0]");
println!(" remove: ports after removing [0] = {:?}", cfg["ports"].as_array().unwrap());
println!("\n\n=== Building a Config from Scratch ===");
let mut built = Config::new();
built.set("title", Value::String("New Config".to_string()));
built.set("debug", Value::Bool(true));
built.set("max_retries", Value::Integer(3));
built.set("timeout_ms", Value::Integer64(30000));
built.set("ratio", Value::Float(0.75));
built.set("tags", Value::Array(vec![
Value::String("prod".to_string()),
Value::String("us-east".to_string()),
]));
built.set("metadata", Value::List(vec![
Value::String("info".to_string()),
Value::Integer(42),
Value::Bool(true),
]));
built.set("options.key", Value::String("value".to_string()));
println!("{}", built.to_string().unwrap());
println!("\n\n=== Final Serialized Output ===");
let output = cfg.to_string().expect("Failed to serialize");
println!("{}", output);
}