use matchy::{Database, QueryResult};
use std::env;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let args: Vec<String> = env::args().collect();
if args.len() < 2 {
eprintln!("Usage: {} <database.mmdb> [ip_address]", args[0]);
eprintln!("\nExample:");
eprintln!(" {} GeoLite2-Country.mmdb 1.1.1.1", args[0]);
eprintln!(" {} GeoLite2-Country.mmdb 8.8.8.8", args[0]);
std::process::exit(1);
}
let db_path = &args[1];
println!("Loading database: {db_path}");
let db = Database::from(db_path).open()?;
println!("Database format: {}\n", db.format());
if args.len() >= 3 {
let ip = &args[2];
query_ip(&db, ip)?;
} else {
println!("Demo mode - querying several IPs:\n");
let demo_ips = vec![
"1.1.1.1", "8.8.8.8", "208.67.222.222", "2001:4860:4860::8888", "127.0.0.1", ];
for ip in demo_ips {
query_ip(&db, ip)?;
println!();
}
}
Ok(())
}
fn query_ip(db: &Database, ip: &str) -> Result<(), Box<dyn std::error::Error>> {
println!("Querying IP: {ip}");
match db.lookup(ip)? {
Some(QueryResult::Ip {
data, prefix_len, ..
}) => {
println!(" ✓ Found in database");
println!(" Prefix length: /{prefix_len}");
println!(" Data: {data:#?}");
}
Some(QueryResult::NotFound) => {
println!(" ✗ Not found in database (e.g., private/reserved IP)");
}
Some(QueryResult::Pattern { .. }) => {
println!(" ! Unexpected pattern result");
}
None => {
println!(" ✗ No result");
}
}
Ok(())
}