| Crates.io | domain-check-lib |
| lib.rs | domain-check-lib |
| version | 0.6.0 |
| created_at | 2025-06-28 11:27:15.503538+00 |
| updated_at | 2025-07-15 03:31:24.679003+00 |
| description | A fast, robust library for checking domain availability using RDAP and WHOIS protocols |
| homepage | https://github.com/saidutt46/domain-check |
| repository | https://github.com/saidutt46/domain-check |
| max_upload_size | |
| id | 1729751 |
| size | 184,213 |
A fast, robust Rust library for checking domain availability using RDAP and WHOIS protocols
Add to your Cargo.toml:
[dependencies]
domain-check-lib = "0.5.0"
tokio = { version = "1", features = ["full"] }
Basic Example:
use domain_check_lib::DomainChecker;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let checker = DomainChecker::new();
let result = checker.check_domain("example.com").await?;
match result.available {
Some(true) => println!("{} is AVAILABLE", result.domain),
Some(false) => println!("{} is TAKEN", result.domain),
None => println!("{} status is UNKNOWN", result.domain),
}
Ok(())
}
🦀 Pure Async Rust - Built with tokio for high performance
🌐 Dual Protocol Support - RDAP-first with WHOIS fallback
⚡ Concurrent Processing - Check multiple domains simultaneously
🎯 30+ TLD Mappings - Accurate results across major registries
🛡️ Robust Error Handling - Comprehensive error types with recovery
📊 Detailed Information - Extract registrar, dates, and status codes
🔄 Streaming Support - Real-time results for bulk operations
use domain_check_lib::{DomainChecker, CheckConfig};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let checker = DomainChecker::new();
let result = checker.check_domain("google.com").await?;
println!("Domain: {}", result.domain);
println!("Available: {:?}", result.available);
println!("Method used: {}", result.method_used);
Ok(())
}
use domain_check_lib::{DomainChecker, CheckConfig};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = CheckConfig::default()
.with_concurrency(20)
.with_detailed_info(true);
let checker = DomainChecker::with_config(config);
let domains = vec![
"example.com".to_string(),
"google.org".to_string(),
"github.io".to_string(),
];
let results = checker.check_domains(&domains).await?;
for result in results {
match result.available {
Some(true) => println!("✅ {} is available", result.domain),
Some(false) => println!("❌ {} is taken", result.domain),
None => println!("❓ {} status unknown", result.domain),
}
}
Ok(())
}
use domain_check_lib::DomainChecker;
use futures::StreamExt;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let checker = DomainChecker::new();
let domains = vec![
"example.com".to_string(),
"startup.org".to_string(),
"mybrand.net".to_string(),
];
let mut stream = checker.check_domains_stream(&domains);
while let Some(result) = stream.next().await {
match result {
Ok(domain_result) => {
println!("✓ {}: {:?}", domain_result.domain, domain_result.available);
}
Err(e) => {
eprintln!("✗ Error: {}", e);
}
}
}
Ok(())
}
use domain_check_lib::{DomainChecker, CheckConfig};
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = CheckConfig::default()
.with_concurrency(50) // Max 50 concurrent checks
.with_timeout(Duration::from_secs(10)) // 10 second timeout
.with_whois_fallback(true) // Enable WHOIS fallback
.with_bootstrap(true) // Use IANA bootstrap
.with_detailed_info(true); // Extract full domain info
let checker = DomainChecker::with_config(config);
let result = checker.check_domain("example.com").await?;
if let Some(duration) = result.check_duration {
println!("Checked in {}ms via {}",
duration.as_millis(),
result.method_used
);
}
Ok(())
}
The library now provides direct access to TLD knowledge for building domain exploration tools:
use domain_check_lib::{get_all_known_tlds, get_preset_tlds, get_available_presets};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Get all TLDs with RDAP endpoints
let all_tlds = get_all_known_tlds();
println!("Checking across {} TLDs", all_tlds.len()); // ~42 TLDs
// Use curated presets for common scenarios
let startup_tlds = get_preset_tlds("startup").unwrap();
println!("Startup TLDs: {:?}", startup_tlds); // 8 tech-focused TLDs
// List available presets
let presets = get_available_presets();
println!("Available presets: {:?}", presets); // ["startup", "enterprise", "country"]
Ok(())
}
Combine TLD management with domain expansion for powerful bulk operations:
use domain_check_lib::{DomainChecker, get_preset_tlds, expand_domain_inputs};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let checker = DomainChecker::new();
// Define base domain names
let base_names = vec!["myapp".to_string(), "mystartup".to_string()];
// Expand with startup-focused TLDs
let startup_tlds = get_preset_tlds("startup");
let domains = expand_domain_inputs(&base_names, &startup_tlds);
// Results in: myapp.com, myapp.io, myapp.ai, etc.
// Check all expanded domains
let results = checker.check_domains(&domains).await?;
// Filter for available domains
let available: Vec<_> = results
.iter()
.filter(|r| r.available == Some(true))
.collect();
println!("Found {} available domains", available.len());
Ok(())
}
🌐 TLD Management: Access to 40+ known TLDs and curated presets
🎯 Smart Expansion: Intelligent domain name expansion with preset integration
📊 Enhanced Results: Improved error context and domain information
use domain_check_lib::{DomainChecker, get_all_known_tlds};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let checker = DomainChecker::new();
// Check against all known TLDs
let all_tlds = get_all_known_tlds();
let domains = domain_check_lib::expand_domain_inputs(
&["myapp".to_string()],
&Some(all_tlds)
);
println!("Checking {} domains across all TLDs", domains.len());
let results = checker.check_domains(&domains).await?;
// Analyze results
let available_count = results.iter().filter(|r| r.available == Some(true)).count();
let taken_count = results.iter().filter(|r| r.available == Some(false)).count();
println!("Results: {} available, {} taken", available_count, taken_count);
Ok(())
}
use domain_check_lib::DomainChecker;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let checker = DomainChecker::new();
// Process domains from a file (one domain per line)
let results = checker.check_domains_from_file("domains.txt").await?;
let available_domains: Vec<_> = results
.iter()
.filter(|r| r.available == Some(true))
.collect();
println!("Found {} available domains out of {}",
available_domains.len(),
results.len()
);
for domain in available_domains {
println!("✅ {}", domain.domain);
}
Ok(())
}
The CheckConfig struct provides extensive configuration:
use domain_check_lib::CheckConfig;
use std::time::Duration;
let config = CheckConfig::default()
.with_concurrency(25) // Concurrent requests (1-100)
.with_timeout(Duration::from_secs(8)) // Per-domain timeout
.with_whois_fallback(true) // Enable WHOIS fallback
.with_bootstrap(false) // IANA bootstrap lookup
.with_detailed_info(true) // Extract registrar details
.with_tlds(vec![ // Default TLDs for expansion
"com".to_string(),
"org".to_string(),
"net".to_string()
]);
pub struct DomainResult {
pub domain: String, // Domain that was checked
pub available: Option<bool>, // true = available, false = taken, None = unknown
pub info: Option<DomainInfo>, // Detailed registration info (if available)
pub check_duration: Option<Duration>, // How long the check took
pub method_used: CheckMethod, // RDAP, WHOIS, or Bootstrap
pub error_message: Option<String>, // Error details (if applicable)
}
pub struct DomainInfo {
pub registrar: Option<String>, // Domain registrar
pub creation_date: Option<String>, // When domain was registered
pub expiration_date: Option<String>, // When domain expires
pub status: Vec<String>, // Domain status codes
pub updated_date: Option<String>, // Last update date
pub nameservers: Vec<String>, // Associated nameservers
}
Domain Check is optimized for high-performance operations:
Comprehensive error types with automatic recovery:
use domain_check_lib::DomainCheckError;
match checker.check_domain("invalid-domain").await {
Ok(result) => println!("Success: {:?}", result),
Err(DomainCheckError::InvalidDomain { domain, reason }) => {
eprintln!("Invalid domain '{}': {}", domain, reason);
}
Err(DomainCheckError::NetworkError { message, .. }) => {
eprintln!("Network error: {}", message);
}
Err(DomainCheckError::Timeout { operation, duration }) => {
eprintln!("Timeout after {:?}: {}", duration, operation);
}
Err(e) => eprintln!("Other error: {}", e),
}
domain-check - Command-line interfaceThis project is licensed under the Apache License, Version 2.0 - see the LICENSE file for details.
Contributions are welcome! Please see the Contributing Guide for details.
Built with ❤️ in Rust