use babbel_bencode::{make_node, Node};
use std::collections::HashMap;
fn main() {
println!("=== Dictionary Manipulation Examples ===\n");
demonstrate_creation();
demonstrate_querying();
demonstrate_modification();
demonstrate_iteration();
demonstrate_nested_operations();
demonstrate_torrent_metadata();
}
fn demonstrate_creation() {
println!("--- Creating Dictionaries ---");
let mut dict1 = HashMap::new();
dict1.insert("key1".to_string(), make_node("value1"));
dict1.insert("key2".to_string(), make_node(42));
let node1 = Node::Dictionary(dict1);
println!("Method 1: {}", node1);
let node2 = Node::Dictionary({
let mut d = HashMap::new();
d.insert("name".to_string(), make_node("Alice"));
d.insert("age".to_string(), make_node(30));
d
});
println!("Method 2: {}", node2);
let mut node3 = Node::Dictionary(HashMap::new());
if let Node::Dictionary(dict) = &mut node3 {
dict.insert("status".to_string(), make_node("active"));
dict.insert("count".to_string(), make_node(100));
}
println!("Method 3: {}\n", node3);
}
fn demonstrate_querying() {
println!("--- Querying Dictionary Values ---");
let mut dict = HashMap::new();
dict.insert("name".to_string(), make_node("Bob"));
dict.insert("score".to_string(), make_node(95));
dict.insert("active".to_string(), make_node(1));
dict.insert(
"tags".to_string(),
make_node(vec![make_node("rust"), make_node("beginner")]),
);
let node = Node::Dictionary(dict);
if let Some(name) = node.get("name") {
println!("Name found: {}", name);
}
println!("Has 'email' key: {}", node.get("email").is_some());
if let Some(score_node) = node.get("score") {
if let Some(score) = score_node.as_integer() {
println!("Score value: {}", score);
if *score >= 90 {
println!(" Grade: A");
}
}
}
if let Some(tags) = node.get("tags") {
if let Some(tag_list) = tags.as_list() {
println!("Tags: {} items", tag_list.len());
for tag in tag_list {
if let Some(s) = tag.as_string() {
println!(" - {}", s);
}
}
}
}
println!();
}
fn demonstrate_modification() {
println!("--- Modifying Dictionaries ---");
let mut dict = HashMap::new();
dict.insert("counter".to_string(), make_node(0));
dict.insert("status".to_string(), make_node("pending"));
let mut node = Node::Dictionary(dict);
println!("Initial: {}", node);
if let Some(counter) = node.get_mut("counter") {
*counter = make_node(5);
}
println!("After incrementing counter: {}", node);
if let Node::Dictionary(dict) = &mut node {
dict.insert("timestamp".to_string(), make_node(1699564800));
}
println!("After adding timestamp: {}", node);
if let Some(status) = node.get_mut("status") {
*status = make_node("completed");
}
println!("After updating status: {}", node);
if let Node::Dictionary(dict) = &mut node {
dict.remove("counter");
}
println!("After removing counter: {}\n", node);
}
fn demonstrate_iteration() {
println!("--- Iterating Through Dictionaries ---");
let mut dict = HashMap::new();
dict.insert("alpha".to_string(), make_node(1));
dict.insert("beta".to_string(), make_node(2));
dict.insert("gamma".to_string(), make_node(3));
dict.insert("delta".to_string(), make_node(4));
let node = Node::Dictionary(dict);
if let Some(dict) = node.as_dictionary() {
println!("All entries:");
for (key, value) in dict {
println!(" {} => {}", key, value);
}
let mut int_count = 0;
let mut str_count = 0;
for (_, value) in dict {
if value.is_integer() {
int_count += 1;
} else if value.is_string() {
str_count += 1;
}
}
println!("Integers: {}, Strings: {}", int_count, str_count);
let mut keys: Vec<_> = dict.keys().collect();
keys.sort();
println!("Sorted keys: {:?}", keys);
}
println!();
}
fn demonstrate_nested_operations() {
println!("--- Nested Dictionary Operations ---");
let mut inner_dict = HashMap::new();
inner_dict.insert("city".to_string(), make_node("New York"));
inner_dict.insert("zip".to_string(), make_node("10001"));
let mut outer_dict = HashMap::new();
outer_dict.insert("name".to_string(), make_node("Charlie"));
outer_dict.insert("address".to_string(), Node::Dictionary(inner_dict));
let mut node = Node::Dictionary(outer_dict);
println!("Nested structure: {}", node);
if let Some(address) = node.get("address") {
if let Some(city) = address.get("city") {
println!("City: {}", city);
}
}
if let Some(address) = node.get_mut("address") {
if let Some(zip) = address.get_mut("zip") {
*zip = make_node("10002");
}
}
println!("After updating zip: {}", node);
if let Some(address) = node.get_mut("address") {
if let Node::Dictionary(dict) = address {
dict.insert("country".to_string(), make_node("USA"));
}
}
println!("After adding country: {}\n", node);
}
fn demonstrate_torrent_metadata() {
println!("--- Building Torrent Metadata ---");
let mut file_info = HashMap::new();
file_info.insert("length".to_string(), make_node(1048576));
file_info.insert(
"path".to_string(),
make_node(vec![make_node("documents"), make_node("readme.txt")]),
);
let mut info_dict = HashMap::new();
info_dict.insert("name".to_string(), make_node("example-file"));
info_dict.insert("piece length".to_string(), make_node(262144));
info_dict.insert("pieces".to_string(), make_node("dummy_hash_value"));
info_dict.insert(
"files".to_string(),
make_node(vec![Node::Dictionary(file_info)]),
);
let mut root = HashMap::new();
root.insert(
"announce".to_string(),
make_node("udp://tracker.example.com:6969/announce"),
);
root.insert("created by".to_string(), make_node("babbel_bencode example"));
root.insert("creation date".to_string(), make_node(1699564800));
root.insert("info".to_string(), Node::Dictionary(info_dict));
let torrent = Node::Dictionary(root);
println!("Torrent structure:");
println!("{}", torrent);
if let Some(announce) = torrent.get("announce") {
println!("\nTracker URL: {}", announce);
}
if let Some(info) = torrent.get("info") {
if let Some(name) = info.get("name") {
println!("Torrent name: {}", name);
}
if let Some(piece_length) = info.get("piece length") {
if let Some(len) = piece_length.as_integer() {
println!("Piece length: {} bytes ({} KB)", len, len / 1024);
}
}
}
println!();
}