use babbel_bencode::{
make_node, parse_borrowed, validate_bencode, stringify, stringify_to_bytes, stringify_to_string,
BufferDestination, Node,
};
use std::collections::HashMap;
fn main() {
println!("=== In-Memory Bencode Operations ===\n");
demonstrate_convenience_functions();
demonstrate_buffer_types();
demonstrate_round_trips();
demonstrate_byte_operations();
}
fn demonstrate_convenience_functions() {
println!("--- Convenience Functions (Zero-Copy Preferred) ---");
let bencode_bytes = b"i42e";
match parse_borrowed(bencode_bytes) {
Ok(node) => println!("Parsed from bytes (zero-copy): {}", node),
Err(e) => eprintln!("Parse error: {}", e),
}
match validate_bencode(bencode_bytes) {
Ok(_) => println!("Validated bencode (no allocation)"),
Err(e) => eprintln!("Validation error: {}", e),
}
let node = make_node(vec![make_node(1), make_node(2), make_node(3)]);
match stringify_to_string(&node) {
Ok(output) => println!("Stringified to string: {}", output),
Err(e) => eprintln!("Stringify error: {}", e),
}
match stringify_to_bytes(&node) {
Ok(output) => println!("Stringified to bytes: {:?}", output),
Err(e) => eprintln!("Stringify error: {}", e),
}
println!();
}
fn demonstrate_buffer_types() {
println!("--- Buffer Types (Zero-Copy Preferred) ---");
let bencode_data = b"d4:name4:John3:agei30e7:hobbieslll7:reading6:codingeee";
match parse_borrowed(bencode_data) {
Ok(node) => {
println!("Parsed dictionary (zero-copy):");
if let Some(dict) = node.as_dictionary() {
for (key, value) in dict {
println!(" {:?}: {:?}", key, value);
}
}
let mut destination = BufferDestination::new();
let node_owned: Node = node.to_node();
match stringify(&node_owned, &mut destination) {
Ok(_) => {
let output = &destination.buffer;
println!("Stringified back: {:?}", output);
println!("As UTF-8: {}", String::from_utf8_lossy(output));
}
Err(e) => eprintln!("Stringify error: {}", e),
}
}
Err(e) => eprintln!("Parse error: {}", e),
}
println!();
}
fn demonstrate_round_trips() {
println!("--- Round-Trip Conversions ---");
let mut dict = HashMap::new();
dict.insert("title".to_string(), make_node("Bencode Example"));
dict.insert("year".to_string(), make_node(2024));
dict.insert(
"tags".to_string(),
make_node(vec![
make_node("rust"),
make_node("bencode"),
make_node("serialization"),
]),
);
let original = Node::Dictionary(dict);
println!("Original: {}", original);
match stringify_to_bytes(&original) {
Ok(bytes) => {
println!("Bencode bytes: {} bytes", bytes.len());
println!("Bencode string: {}", String::from_utf8_lossy(&bytes));
match parse_borrowed(&bytes) {
Ok(parsed) => {
let parsed_owned: Node = parsed.to_node();
println!("Parsed back: {}", parsed_owned);
println!("Matches original: {}", original == parsed_owned);
}
Err(e) => eprintln!("Parse error: {}", e),
}
}
Err(e) => eprintln!("Stringify error: {}", e),
}
println!();
}
fn demonstrate_byte_operations() {
println!("--- Byte Operations ---");
let examples = vec![
("Integer", b"i-123e" as &[u8]),
("String", b"11:hello world"),
("Empty list", b"le"),
("List with items", b"li1ei2ei3ee"),
("Empty dict", b"de"),
("Simple dict", b"d3:key5:valuee"),
];
for (description, bytes) in examples {
print!("{}: ", description);
match parse_borrowed(bytes) {
Ok(node) => {
let node_owned: Node = node.to_node();
println!("{:?}", node_owned);
if let Ok(output) = stringify_to_bytes(&node_owned) {
if output == bytes {
println!(" ✓ Round-trip successful");
} else {
println!(" ✗ Round-trip mismatch: {:?} != {:?}", output, bytes);
}
}
}
Err(e) => println!("Parse error: {}", e),
}
}
println!();
}