use std::error::Error;
use std::net::IpAddr;
use std::path::Path;
use libmaxminddb_rs::{MetadataBuilder, MmdbDecode, MmdbEncode, Reader, Writer};
#[derive(Debug, PartialEq, MmdbEncode, MmdbDecode)]
struct NetworkPolicy<'a> {
zone: &'a str,
rate_limit_rps: u32,
allowed_protocols: Vec<&'a str>,
}
fn main() -> Result<(), Box<dyn Error>> {
println!("=== libmaxminddb-rs Custom Database Builder Example ===\n");
let db_path = Path::new("target/custom_policy.mmdb");
println!("1. Configuring database metadata...");
let metadata = MetadataBuilder::new()
.database_type("Network-Policy-DB")
.ip_version(6)
.build_epoch(1700000000)
.language("en")
.language("fr")
.description("en", "Custom network policy routing database")
.description("fr", "Base de données de politiques réseau")
.build()?;
let mut writer = Writer::with_metadata(metadata);
println!("2. Inserting network policy rules...");
writer.insert_encoded(
"10.0.0.0/8".parse()?,
&NetworkPolicy {
zone: "internal_trusted",
rate_limit_rps: 50_000,
allowed_protocols: vec!["https", "ssh", "grpc"],
},
)?;
writer.insert_encoded(
"198.51.100.0/24".parse()?,
&NetworkPolicy {
zone: "dmz_public",
rate_limit_rps: 1_000,
allowed_protocols: vec!["https"],
},
)?;
writer.insert_encoded(
"2001:db8:acad::/48".parse()?,
&NetworkPolicy {
zone: "ipv6_management",
rate_limit_rps: 10_000,
allowed_protocols: vec!["https", "ssh"],
},
)?;
println!("3. Writing database to: {}", db_path.display());
std::fs::create_dir_all(db_path.parent().unwrap())?;
writer.write_to_file(db_path)?;
let file_size = std::fs::metadata(db_path)?.len();
println!(
" File successfully created (size: {} bytes).\n",
file_size
);
println!("4. Re-opening with zero-copy memory mapping (`open_mmap`)...");
let reader = unsafe { Reader::open_mmap(db_path)? };
let meta = reader.metadata();
println!(" ↳ Database Type : {}", meta.database_type);
println!(" ↳ IP Version : IPv{}", meta.ip_version);
println!(" ↳ Record Size : {} bits", meta.record_size);
println!(" ↳ Node Count : {}", meta.node_count);
println!("\n5. Querying policies across address families:");
let queries: &[(&str, &str)] = &[
("10.50.1.20", "IPv4 internal address"),
("198.51.100.5", "IPv4 DMZ address"),
("2001:db8:acad::1", "IPv6 management address"),
];
for &(ip_str, desc) in queries {
let ip: IpAddr = ip_str.parse()?;
let policy: NetworkPolicy<'_> = reader.lookup_borrowed(ip)?;
println!(" IP: {} ({})", ip, desc);
println!(" ↳ Zone : {}", policy.zone);
println!(" ↳ Rate Limit : {} rps", policy.rate_limit_rps);
println!(" ↳ Protocols : {:?}\n", policy.allowed_protocols);
}
let _ = std::fs::remove_file(db_path);
println!("Custom database builder example completed successfully!");
Ok(())
}