examples/ directory.
Basic Query
Simple domain query with colored output:examples/basic_query.rs
use rdap::{QueryType, RdapClient, RdapRequest, display::RdapDisplay};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();
// Create a client
let client = RdapClient::new()?;
// Create a domain query
let request = RdapRequest::new(QueryType::Domain, "example.com");
// Execute the query
println!("Querying example.com...\n");
let result = client.query(&request).await?;
// Display the result with colors
result.display(true);
Ok(())
}
examples/basic_query.rs
The
RdapDisplay trait provides colored terminal output. Set the boolean parameter to true for colors.Auto-Detection
Automatically detect query type from input:examples/auto_detect.rs
use rdap::{RdapClient, RdapRequest};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = RdapClient::new()?;
// Query different types - type is auto-detected
let queries = vec![
"example.com", // Domain
"8.8.8.8", // IPv4
"2001:4860:4860::8888", // IPv6
"AS15169", // AS number
];
for query in queries {
println!("\n=== Querying: {} ===", query);
// Auto-detect query type
let query_type = RdapRequest::detect_type(query)?;
println!("Detected type: {:?}", query_type);
let request = RdapRequest::new(query_type, query);
let result = client.query(&request).await?;
// Display result
use rdap::display::RdapDisplay;
result.display(false);
}
Ok(())
}
examples/auto_detect.rs
Domain Information Extraction
Extract specific fields from a domain response:examples/domain_info.rs
use rdap::{QueryType, RdapClient, RdapObject, RdapRequest};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = RdapClient::new()?;
let request = RdapRequest::new(QueryType::Domain, "example.com");
let result = client.query(&request).await?;
if let RdapObject::Domain(domain) = result {
println!("=== Domain Information ===\n");
// Basic info
if let Some(name) = &domain.ldh_name {
println!("Domain: {}", name);
}
if let Some(handle) = &domain.handle {
println!("Handle: {}", handle);
}
// Status
println!("\nStatus:");
for status in &domain.status {
println!(" - {}", status);
}
// Nameservers
println!("\nNameservers:");
for ns in &domain.nameservers {
if let Some(name) = &ns.ldh_name {
print!(" - {}", name);
if let Some(ips) = &ns.ip_addresses {
let addrs: Vec<String> = ips.v4.iter().chain(&ips.v6).cloned().collect();
if !addrs.is_empty() {
print!(" ({})", addrs.join(", "));
}
}
println!();
}
}
// DNSSEC
if let Some(dnssec) = &domain.secure_dns {
println!("\nDNSSEC:");
if let Some(signed) = dnssec.delegation_signed {
println!(" Delegation Signed: {}", if signed { "Yes" } else { "No" });
}
if let Some(signed) = dnssec.zone_signed {
println!(" Zone Signed: {}", if signed { "Yes" } else { "No" });
}
// DS records
if !dnssec.ds_data.is_empty() {
println!("\n DS Records:");
for ds in &dnssec.ds_data {
if let (Some(tag), Some(alg), Some(digest_type)) =
(ds.key_tag, ds.algorithm, ds.digest_type)
{
println!(
" - Key Tag: {}, Algorithm: {}, Digest Type: {}",
tag, alg, digest_type
);
if let Some(digest) = &ds.digest {
println!(" Digest: {}", digest);
}
}
}
}
}
// Events
println!("\nImportant Dates:");
for event in &domain.events {
match event.action.as_str() {
"registration" => println!(" Registered: {}", event.date),
"expiration" => println!(" Expires: {}", event.date),
"last changed" => println!(" Last Updated: {}", event.date),
_ => {}
}
}
// Entities
println!("\nEntities:");
for entity in &domain.entities {
if let Some(handle) = &entity.handle {
println!(" - {} ({})", handle, entity.roles.join(", "));
if let Some(vcard) = &entity.vcard {
if let Some(name) = vcard.name() {
println!(" Name: {}", name);
}
if let Some(email) = vcard.email() {
println!(" Email: {}", email);
}
}
}
}
}
Ok(())
}
examples/domain_info.rs
IP Lookup
Query IP network information:examples/ip_lookup.rs
use rdap::{QueryType, RdapClient, RdapObject, RdapRequest};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = RdapClient::new()?;
// Query an IP address
let ip = "8.8.8.8";
let request = RdapRequest::new(QueryType::Ip, ip);
let result = client.query(&request).await?;
if let RdapObject::IpNetwork(network) = result {
println!("=== IP Network Information ===\n");
if let Some(name) = &network.name {
println!("Network Name: {}", name);
}
if let Some(handle) = &network.handle {
println!("Handle: {}", handle);
}
if let (Some(start), Some(end)) = (&network.start_address, &network.end_address) {
println!("Address Range: {} - {}", start, end);
}
if let Some(version) = &network.ip_version {
println!("IP Version: IPv{}", version);
}
if let Some(net_type) = &network.network_type {
println!("Network Type: {}", net_type);
}
if let Some(country) = &network.country {
println!("Country: {}", country);
}
if let Some(parent) = &network.parent_handle {
println!("Parent Network: {}", parent);
}
// Status
if !network.status.is_empty() {
println!("\nStatus:");
for status in &network.status {
println!(" - {}", status);
}
}
// Entities
if !network.entities.is_empty() {
println!("\nContacts:");
for entity in &network.entities {
if let Some(handle) = &entity.handle {
println!(" - {} ({})", handle, entity.roles.join(", "));
if let Some(vcard) = &entity.vcard {
if let Some(name) = vcard.name() {
println!(" Name: {}", name);
}
if let Some(org) = vcard.org() {
println!(" Organization: {}", org);
}
}
}
}
}
}
Ok(())
}
examples/ip_lookup.rs
AS Number Lookup
Query Autonomous System information:examples/asn_lookup.rs
use rdap::{QueryType, RdapClient, RdapObject, RdapRequest};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = RdapClient::new()?;
// Query an AS number
let asn = "AS15169";
let request = RdapRequest::new(QueryType::Autnum, asn);
let result = client.query(&request).await?;
if let RdapObject::Autnum(autnum) = result {
println!("=== AS Number Information ===\n");
if let Some(start) = autnum.start_autnum {
if let Some(end) = autnum.end_autnum {
if start == end {
println!("AS Number: AS{}", start);
} else {
println!("AS Range: AS{} - AS{}", start, end);
}
}
}
if let Some(name) = &autnum.name {
println!("Name: {}", name);
}
if let Some(handle) = &autnum.handle {
println!("Handle: {}", handle);
}
if let Some(as_type) = &autnum.as_type {
println!("Type: {}", as_type);
}
if let Some(country) = &autnum.country {
println!("Country: {}", country);
}
// Status
if !autnum.status.is_empty() {
println!("\nStatus:");
for status in &autnum.status {
println!(" - {}", status);
}
}
// Events
if !autnum.events.is_empty() {
println!("\nEvents:");
for event in &autnum.events {
println!(" {}: {}", event.action, event.date);
}
}
// Entities
if !autnum.entities.is_empty() {
println!("\nContacts:");
for entity in &autnum.entities {
if let Some(handle) = &entity.handle {
println!("\n {} ({})", handle, entity.roles.join(", "));
if let Some(vcard) = &entity.vcard {
if let Some(name) = vcard.name() {
println!(" Name: {}", name);
}
if let Some(org) = vcard.org() {
println!(" Organization: {}", org);
}
if let Some(email) = vcard.email() {
println!(" Email: {}", email);
}
if let Some(tel) = vcard.tel() {
println!(" Phone: {}", tel);
}
if let Some(addr) = vcard.address() {
if let Some(label) = &addr.label {
println!(" Address: {}", label);
}
}
}
}
}
}
}
Ok(())
}
examples/asn_lookup.rs
Error Handling
Comprehensive error handling:examples/error_handling.rs
use rdap::{QueryType, RdapClient, RdapError, RdapObject, RdapRequest};
#[tokio::main]
async fn main() {
let client = RdapClient::new().unwrap();
// Try queries that might fail
let queries = vec![
("nonexistent-domain-12345.com", QueryType::Domain),
("999.999.999.999", QueryType::Ip),
("AS99999999", QueryType::Autnum),
];
for (query, query_type) in queries {
println!("\n=== Querying: {} ===", query);
let request = RdapRequest::new(query_type, query);
match client.query(&request).await {
Ok(result) => {
// Check if it's an error response from the RDAP server
match result {
RdapObject::Error(err) => {
println!("❌ RDAP Error Response:");
if let Some(code) = err.error_code {
println!(" Code: {}", code);
}
if let Some(title) = &err.title {
println!(" Title: {}", title);
}
for desc in &err.description {
println!(" Description: {}", desc);
}
}
_ => {
println!("✅ Query successful");
use rdap::display::RdapDisplay;
result.display(false);
}
}
}
Err(e) => {
println!("❌ Client Error:");
match e {
RdapError::Bootstrap(msg) => {
println!(" Bootstrap error: {}", msg);
println!(" (Try specifying a server with -s option)");
}
RdapError::Http(err) => {
println!(" HTTP error: {}", err);
}
RdapError::InvalidQuery(msg) => {
println!(" Invalid query: {}", msg);
}
RdapError::Json(err) => {
println!(" JSON parse error: {}", err);
}
RdapError::InvalidUrl(err) => {
println!(" URL error: {}", err);
}
RdapError::Io(err) => {
println!(" I/O error: {}", err);
}
_ => {
println!(" Other error: {}", e);
}
}
}
}
}
}
examples/error_handling.rs
Batch Queries
Query multiple resources with rate limiting:examples/batch_query.rs
use rdap::{RdapClient, RdapRequest};
use tokio::time::{Duration, sleep};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = RdapClient::new()?;
// List of domains to query
let queries = vec!["example.com", "google.com", "github.com", "rust-lang.org"];
println!("Querying {} domains...\n", queries.len());
for query in queries {
println!("=== {} ===", query);
// Auto-detect type
let query_type = RdapRequest::detect_type(query)?;
let request = RdapRequest::new(query_type, query);
match client.query(&request).await {
Ok(result) => {
use rdap::display::RdapDisplay;
result.display(false);
}
Err(e) => {
eprintln!("Error querying {}: {}", query, e);
}
}
println!();
// Be nice to the server - add a small delay
sleep(Duration::from_millis(500)).await;
}
Ok(())
}
examples/batch_query.rs
Custom Server
Query a specific RDAP server:examples/custom_server.rs
use rdap::{QueryType, RdapClient, RdapRequest, display::RdapDisplay};
use url::Url;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
env_logger::init();
let client = RdapClient::new()?;
// Query with a specific RDAP server
let server = Url::parse("https://rdap.nic.cz")?;
let request = RdapRequest::new(QueryType::Domain, "nic.cz").with_server(server);
println!("Querying nic.cz via rdap.nic.cz...\n");
let result = client.query(&request).await?;
result.display(true);
Ok(())
}
examples/custom_server.rs
JSON Output
Serialize results to JSON:examples/json_output.rs
use rdap::{QueryType, RdapClient, RdapRequest};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = RdapClient::new()?;
let request = RdapRequest::new(QueryType::Domain, "example.com");
let result = client.query(&request).await?;
// Output as pretty JSON
let json = serde_json::to_string_pretty(&result)?;
println!("{}", json);
Ok(())
}
examples/json_output.rs
Complete Example
Demonstrates multiple features:View complete example (204 lines)
View complete example (204 lines)
examples/complete_example.rs
use rdap::{RdapClient, RdapError, RdapObject, RdapRequest};
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== RDAP Library Complete Example ===\n");
// Create a client with custom timeout
let client = RdapClient::new()?.with_timeout(Duration::from_secs(30));
// Example 1: Domain query with detailed information extraction
println!("1. Domain Query:");
query_domain(&client, "example.com").await?;
println!("\n{}\n", "=".repeat(60));
// Example 2: IP address query
println!("2. IP Address Query:");
query_ip(&client, "8.8.8.8").await?;
println!("\n{}\n", "=".repeat(60));
// Example 3: AS number query
println!("3. AS Number Query:");
query_asn(&client, "AS15169").await?;
println!("\n{}\n", "=".repeat(60));
// Example 4: Error handling
println!("4. Error Handling:");
demonstrate_error_handling(&client).await;
Ok(())
}
async fn query_domain(client: &RdapClient, domain: &str) -> Result<(), Box<dyn std::error::Error>> {
let query_type = RdapRequest::detect_type(domain)?;
let request = RdapRequest::new(query_type, domain);
let result = client.query(&request).await?;
if let RdapObject::Domain(domain_obj) = result {
// Extract basic information
if let Some(name) = &domain_obj.ldh_name {
println!(" Domain: {}", name);
}
// Status information
if !domain_obj.status.is_empty() {
println!(" Status: {}", domain_obj.status.join(", "));
}
// Nameservers
if !domain_obj.nameservers.is_empty() {
println!(" Nameservers:");
for ns in &domain_obj.nameservers {
if let Some(name) = &ns.ldh_name {
println!(" - {}", name);
}
}
}
// DNSSEC status
if let Some(dnssec) = &domain_obj.secure_dns {
if let Some(signed) = dnssec.delegation_signed {
println!(" DNSSEC: {}", if signed { "Enabled" } else { "Disabled" });
}
}
// Important dates
for event in &domain_obj.events {
match event.action.as_str() {
"registration" => println!(" Registered: {}", event.date),
"expiration" => println!(" Expires: {}", event.date),
_ => {}
}
}
}
Ok(())
}
async fn query_ip(client: &RdapClient, ip: &str) -> Result<(), Box<dyn std::error::Error>> {
let query_type = RdapRequest::detect_type(ip)?;
let request = RdapRequest::new(query_type, ip);
let result = client.query(&request).await?;
if let RdapObject::IpNetwork(network) = result {
if let Some(name) = &network.name {
println!(" Network: {}", name);
}
if let (Some(start), Some(end)) = (&network.start_address, &network.end_address) {
println!(" Range: {} - {}", start, end);
}
if let Some(country) = &network.country {
println!(" Country: {}", country);
}
// Find registrant
for entity in &network.entities {
if entity.roles.contains(&"registrant".to_string()) {
if let Some(vcard) = &entity.vcard {
if let Some(org) = vcard.name() {
println!(" Organization: {}", org);
}
}
break;
}
}
}
Ok(())
}
async fn query_asn(client: &RdapClient, asn: &str) -> Result<(), Box<dyn std::error::Error>> {
let query_type = RdapRequest::detect_type(asn)?;
let request = RdapRequest::new(query_type, asn);
let result = client.query(&request).await?;
if let RdapObject::Autnum(autnum) = result {
if let Some(start) = autnum.start_autnum {
println!(" AS Number: AS{}", start);
}
if let Some(name) = &autnum.name {
println!(" Name: {}", name);
}
if let Some(country) = &autnum.country {
println!(" Country: {}", country);
}
// Count entities by role
let mut role_counts = std::collections::HashMap::new();
for entity in &autnum.entities {
for role in &entity.roles {
*role_counts.entry(role.clone()).or_insert(0) += 1;
}
}
if !role_counts.is_empty() {
println!(" Contacts:");
for (role, count) in role_counts {
println!(" - {}: {}", role, count);
}
}
}
Ok(())
}
async fn demonstrate_error_handling(client: &RdapClient) {
let test_queries = vec!["nonexistent-domain-xyz123.com", "999.999.999.999"];
for query in test_queries {
println!(" Testing: {}", query);
let query_type = match RdapRequest::detect_type(query) {
Ok(qt) => qt,
Err(e) => {
println!(" ❌ Invalid query: {}", e);
continue;
}
};
let request = RdapRequest::new(query_type, query);
match client.query(&request).await {
Ok(result) => match result {
RdapObject::Error(err) => {
println!(" ⚠️ RDAP Error:");
if let Some(title) = &err.title {
println!(" {}", title);
}
}
_ => {
println!(" ✅ Query successful");
}
},
Err(e) => match e {
RdapError::Bootstrap(msg) => {
println!(" ❌ Bootstrap error: {}", msg);
}
RdapError::NotFound => {
println!(" ℹ️ Object not found");
}
_ => {
println!(" ❌ Error: {}", e);
}
},
}
}
}
examples/complete_example.rs
Running Examples
Run examples usingcargo run --example:
# Basic query
cargo run --example basic_query
# Auto-detect query type
cargo run --example auto_detect
# Domain information extraction
cargo run --example domain_info
# IP lookup
cargo run --example ip_lookup
# AS number lookup
cargo run --example asn_lookup
# Error handling
cargo run --example error_handling
# Batch queries
cargo run --example batch_query
# Custom server
cargo run --example custom_server
# JSON output
cargo run --example json_output
# Complete example
cargo run --example complete_example
Next Steps
Getting Started
Back to getting started guide
API Reference
Browse the full API documentation
