Observed since 20 Oct, 16:59 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Python bindings for the aam-rs AAML configuration parser
A robust and lightweight configuration parser for Rust that supports key-value pairs, recursive dependency resolution, file imports, and bidirectional lookups. Designed for applications that need flexible configuration files with references, aliases, and a modular structure.
key = value format that is easy to read and write.@import directive lets you split configuration into multiple files.# are treated as comments.find_deep): Automatically resolves chains of references (e.g., A -> B -> C) to find the final value.A -> B -> A) without stack overflows.find_obj): Looks up a value by key, or performs a reverse lookup (finds a key by value) when the key is missing.AAMBuilder): Programmatically generate and save .aam files.+ operator to combine two AAML instances.AamlError.You can find documentation and examples for the format in the docs
Add the library to your Cargo.toml:
[dependencies]
aam-rs = "1.2.4"
The format is line-based. Whitespace around keys and values is trimmed. Strings can be quoted.
# This is a comment
host = "localhost"
port = 8080
# Import other configuration files
@import database.aam
@import theme.aam
# You can define aliases for deep lookup
base_path = /var/www
current_path = base_path
# Circular references are handled safely
loop_a = loop_b
loop_b = loop_a
You can parse configuration from a string, load it from a file, or merge multiple sources. Errors are handled via AamlError.
use aaml::aaml::AAML;
use aaml::error::AamlError;
fn main() -> Result<(), AamlError> {
// 1. Parse from string
let content = "
username = admin
timeout = 30
";
let config = AAML::parse(content)?;
// 2. Load from file (supports @import directives)
let file_config = AAML::load("config.aam")?;
Ok(())
}
Combine different AAML objects using the addition operator.
let mut config1 = AAML::parse("a = 1")?;
let config2 = AAML::parse("b = 2")?;
// Merge (config2 overwrites matching keys in config1)
config1 += config2;
// or: let config3 = config1 + config2;
find_obj is a hybrid lookup method. It first tries to find a value by the given key. If the key does not exist, it searches for a key whose value matches the provided string.
let content = "
# Key = Value
app_mode = production
debug = false
";
let config = AAML::parse(content)?;
// Scenario A: Direct key lookup
let mode = config.find_obj("app_mode").unwrap();
assert_eq!(mode, "production");
// Scenario B: Reverse lookup
// "production" is not a key, so it looks for a key with value "production"
let key = config.find_obj("production").unwrap();
assert_eq!(key, "app_mode");
This is useful for aliasing. It follows values as keys until it reaches a value that is not present as a key, or until a loop is detected.
let content = "
root = /usr/bin
executable = root
service = executable
";
let config = AAML::parse(content)?;
// Traces: "service" -> "executable" -> "root" -> "/usr/bin"
let final_val = config.find_deep("service").unwrap();
assert_eq!(final_val, "/usr/bin");
Handling loops: If the configuration contains a loop (e.g., a=b, b=a), find_deep returns the last unique value visited before the loop closes, preventing infinite recursion.
Use AAMBuilder to generate configuration files programmatically.
use aam_rs::builder::{AAMBuilder, SchemaField};
let mut builder = AAMBuilder::new();
builder.comment("Server configuration")
.type_alias("port_t", "i32")
.schema("Server", [
SchemaField::required("host", "string"),
SchemaField::required("port", "port_t"),
SchemaField::optional("debug", "bool"),
])
.add_line("host", "127.0.0.1")
.add_line("port", "8000");
// Save to file
builder.to_file("generated_config.aam");
// Or convert to string
println!("{}", builder);
Lookup results are wrapped in a FoundValue struct. It implements Deref<Target=String> and Display, so you can use it like a regular &str or String. It also provides helper methods for in-place modification.
let config = AAML::parse("greeting = Hello World")?;
let mut value = config.find_obj("greeting").unwrap();
// Use as a string
println!("Original: {}", value); // Prints: Hello World
// Modify in-place using the helper method
value.remove(" World");
assert_eq!(value.as_str(), "Hello");
parse(content: &str) -> Result<Self, AamlError>: Parses a string into an AAML map.load<P: AsRef<Path>>(file_path: P) -> Result<Self, AamlError>: Loads and parses a file, handling imports.merge_content(&mut self, content: &str) -> Result<(), AamlError>: Merges content into the current instance.merge_file<P: AsRef<Path>>(&mut self, path: P) -> Result<(), AamlError>: Reads a file and merges it.find_obj(&self, key: &str) -> Option<FoundValue>: Smart bidirectional lookup.find_deep(&self, key: &str) -> Option<FoundValue>: Recursive lookup with loop detection.find_key(&self, value: &str) -> Option<FoundValue>: Strict reverse lookup (find key by value).new() -> Self: Creates a new builder.add_line(key: &str, value: &str): Adds a key = value pair.comment(text: &str): Adds a # text comment line.schema(name: &str, fields: impl IntoIterator<Item = SchemaField>): Adds a @schema Name { ... } directive (inline).schema_multiline(name: &str, fields: impl IntoIterator<Item = SchemaField>): Adds a @schema Name { ... } directive (one field per line).derive(path: &str, schemas: impl IntoIterator<Item = impl AsRef<str>>): Adds a @derive path[::Schema...] directive.import(path: &str): Adds a @import path directive.type_alias(alias: &str, type_name: &str): Adds a @type alias = type_name directive.add_raw(raw_line: &str) (deprecated): Adds a raw line as-is. Prefer the typed methods above.to_file<P: AsRef<Path>>(&self, path: P): Writes the buffer to a file.IoError: Wraps standard I/O errors.ParseError: Syntax errors (includes line number and details).NotFound: Key not found (internal use).See the LICENSE file.
Full API documentation is available at docs.rs/aaml or in main documentation of AAM.
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 1.4.0 | 12 Mar 2026 | 0 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 16:59 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:f318da71e807eb0f2667ec01d1ff545df5eff53c37affecf89ed9eda06cfa3d1