use confetti_rs::{parse, ConfOptions};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let comments_example = r#"
# Confetti style comment.
// C-style single-line comment.
/* C-style multi-
line comment. */
server {
listen 80; # Standard comment
/* Multi-line comment
explaining server config */
server_name example.com;
}
"#;
let expressions_example = r#"
if (x > y) {
print "x is greater than y"
}
while (count < 10) {
increment count
print (count * 2)
}
"#;
let punctuators_example = r#"
x = 123
y=456
config-file = "/etc/app.conf"
database {
host = "localhost"
port = 5432
credentials = { username = "admin", password = "secret" }
}
"#;
println!("Example 1: Comment Syntax Extension (Annex A)");
let comment_options = ConfOptions {
allow_c_style_comments: true,
..ConfOptions::default()
};
let comment_conf = parse(comments_example, comment_options)?;
println!("Parsed configuration with C-style comments:");
println!(
"Found {} directives and {} comments",
comment_conf.directives.len(),
comment_conf.comments.len()
);
println!("\nComments:");
for (i, comment) in comment_conf.comments.iter().enumerate() {
println!("Comment {}: {}", i + 1, comment.content);
println!(" Is multi-line: {}", comment.is_multi_line);
}
println!("\nExample 2: Expression Arguments Extension (Annex B)");
let expr_options = ConfOptions {
allow_expression_arguments: true,
..ConfOptions::default()
};
let expr_conf = parse(expressions_example, expr_options)?;
println!("Parsed configuration with expression arguments:");
fn print_expression_directives(directives: &[confetti_rs::ConfDirective], indent: usize) {
let indent_str = " ".repeat(indent * 2);
for directive in directives {
print!("{}Directive: {}", indent_str, directive.name.value);
for arg in &directive.arguments {
if arg.is_expression {
print!(" Expression[{}]", arg.value);
} else {
print!(" {}", arg.value);
}
}
println!();
if !directive.children.is_empty() {
print_expression_directives(&directive.children, indent + 1);
}
}
}
print_expression_directives(&expr_conf.directives, 0);
println!("\nExample 3: Punctuator Arguments Extension (Annex C)");
let punct_conf = parse(punctuators_example, ConfOptions::default())?;
println!("Parsed configuration with punctuators:");
fn process_punctuator_directives(directives: &[confetti_rs::ConfDirective], indent: usize) {
let indent_str = " ".repeat(indent * 2);
for directive in directives {
if directive.arguments.len() >= 2 && directive.arguments[0].value == "=" {
println!(
"{}Assignment: {} = {}",
indent_str, directive.name.value, directive.arguments[1].value
);
} else {
println!("{}Directive: {}", indent_str, directive.name.value);
for arg in &directive.arguments {
println!("{} Argument: {}", indent_str, arg.value);
}
if !directive.children.is_empty() {
process_punctuator_directives(&directive.children, indent + 1);
}
}
}
}
process_punctuator_directives(&punct_conf.directives, 0);
println!("\nExample 4: Using All Extensions Together");
let combined_example = r#"
// Configuration with all extensions
/* This is a multi-line comment
explaining the configuration */
# Server configuration
server {
listen = 80; // Port to listen on
if (debug_mode == true) {
log-level = "debug"
} else {
log-level = "info"
}
locations = {
"/api" = { proxy_pass = "http://api-server:8080" },
"/static" = { root = "/var/www/static" }
}
}
"#;
let all_options = ConfOptions {
allow_c_style_comments: true,
allow_expression_arguments: true,
..ConfOptions::default()
};
let combined_conf = parse(combined_example, all_options)?;
println!("Parsed configuration with all extensions:");
println!(
"Found {} directives and {} comments",
combined_conf.directives.len(),
combined_conf.comments.len()
);
fn print_combined_config(directives: &[confetti_rs::ConfDirective], indent: usize) {
let indent_str = " ".repeat(indent * 2);
for directive in directives {
print!("{}Directive: {}", indent_str, directive.name.value);
for arg in &directive.arguments {
if arg.is_expression {
print!(" Expression[{}]", arg.value);
} else if arg.is_quoted {
print!(" Quoted[{}]", arg.value);
} else {
print!(" {}", arg.value);
}
}
println!();
if !directive.children.is_empty() {
print_combined_config(&directive.children, indent + 1);
}
}
}
print_combined_config(&combined_conf.directives, 0);
Ok(())
}