| Crates.io | uiniparser |
| lib.rs | uiniparser |
| version | 0.1.0 |
| created_at | 2025-12-01 18:11:43.551576+00 |
| updated_at | 2025-12-01 18:11:43.551576+00 |
| description | A robust INI parser for Rust with variable substitution, environment support, and typed getters. |
| homepage | |
| repository | https://github.com/userx007/uRustIniParser |
| max_upload_size | |
| id | 1960246 |
| size | 30,640 |
IniParserEx is a lightweight and robust INI file parser for Rust.
It supports:
${Section:key}${ENV:VAR} with optional fallback ${ENV:VAR:-default}get_string, get_bool, get_int, get_floatPerfect for configuration files and projects that require flexible INI parsing.
HashMap<String, String>; or #) and empty linesAdd this to your Cargo.toml:
[dependencies]
uiniparser = "0.1.0"
Then include it in your project:
use uiniparser::IniParserEx;
use uiniparser::IniParserEx;
fn main() {
let mut parser = IniParserEx::default();
if parser.load("config.ini").is_ok() {
// String with automatic fallback
let path = parser.get_string("Common", "path", 5).unwrap_or("/default/path".to_string());
println!("Common.path = {}", path);
// Boolean
let enabled = parser.get_bool("Common", "enabled", 5).unwrap_or(false);
println!("Common.enabled = {}", enabled);
// Integer
let port = parser.get_int("Common", "port", 5).unwrap_or(8080);
println!("Common.port = {}", port);
// Float
let factor = parser.get_float("Common", "factor", 5).unwrap_or(1.0);
println!("Common.factor = {}", factor);
// Fully resolved section
if let Ok(section) = parser.get_resolved_section("Common", 5) {
println!("Resolved Common section:");
for (k, v) in section {
println!(" {} = {}", k, v);
}
}
} else {
println!("Failed to load INI file.");
}
}
#--------------------------------
# Common settings
#--------------------------------
[COMMON]
FAULT_TOLERANT = FALSE
UART_PORT = COM1
PORT = 1234
ENABLED = true
FACTOR = 1.234
#--------------------------------
# Plugin settings
#--------------------------------
[UTILS]
FAULT_TOLERANT = ${COMMON:FAULT_TOLERANT}
PRIVILEGED = FALSE
UART_PORT = ${COMMON:UART_PORT}
[MATH]
FAULT_TOLERANT = ${COMMON:FAULT_TOLERANT}
PRIVILEGED = TRUE
UART_PORT = ${COMMON:UART_PORT}
[ENV_TEST]
HOST = ${ENV:TEST_HOST:-localhost}
HOME_DIR = ${ENV:HOME}
let uart = parser.get_string("UTILS", "UART_PORT", 5).unwrap();
// "COM1"
let priv_math = parser.get_bool("MATH", "PRIVILEGED", 5).unwrap();
// true
std::env::set_var("TEST_HOST", "myhost.local");
let host = parser.get_string("ENV_TEST", "HOST", 5).unwrap();
// "myhost.local"
let fallback_host = parser.get_string("ENV_TEST", "NON_EXISTENT", 5)
.unwrap_or("default_host".to_string());
// "default_host"
let port = parser.get_int("COMMON", "PORT", 5).unwrap();
// 1234
let factor = parser.get_float("COMMON", "FACTOR", 5).unwrap();
// 1.234
let enabled = parser.get_bool("COMMON", "ENABLED", 5).unwrap();
// true
This crate includes unit tests covering:
Loading INI files
Section/key parsing
Variable substitution and recursive resolution
Environment-variable resolution with fallback
Typed getters (get_string, get_bool, get_int, get_float)
Circular reference detection
Missing keys or sections
Run tests with:
cargo test
use std::env;
use std::process;
use uiniparser::IniParserEx;
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
eprintln!("Usage: parse_ini <path-to-ini-file>");
process::exit(1);
}
let filename = &args[1];
let mut parser = IniParserEx::default();
if let Err(e) = parser.load(filename) {
eprintln!("Failed to load INI file {}: {:?}", filename, e);
process::exit(1);
}
println!("Loaded INI file: {}\n", filename);
println!("=== RESOLVED SECTIONS ===");
for (section, _) in parser.ini_data.iter() {
println!("[{}]", section);
if let Ok(resolved) = parser.get_resolved_section(section, 10) {
for (key, val) in resolved {
println!(" {} = {}", key, val);
}
}
println!();
}
// Example direct lookups
let uart_port = parser.get_string("UTILS", "UART_PORT", 10).unwrap_or("<missing>".to_string());
println!("UTILS.UART_PORT = {}", uart_port);
let priv_math = parser.get_bool("MATH", "PRIVILEGED", 10).unwrap_or(false);
println!("MATH.PRIVILEGED = {}", priv_math);
let port = parser.get_int("COMMON", "PORT", 10).unwrap_or(8080);
println!("COMMON.PORT = {}", port);
let factor = parser.get_float("COMMON", "FACTOR", 10).unwrap_or(1.0);
println!("COMMON.FACTOR = {}", factor);
let host = parser.get_string("ENV_TEST", "HOST", 10).unwrap_or("<missing>".to_string());
println!("ENV_TEST.HOST = {}", host);
let home = parser.get_string("ENV_TEST", "HOME_DIR", 10).unwrap_or("<missing>".to_string());
println!("ENV_TEST.HOME_DIR = {}", home);
}
Run it with:
cargo run --example parseini ./data/testcfg.ini