1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//! # ipwhois
//!
//! Official, async Rust client for the [ipwhois.io](https://ipwhois.io) IP
//! Geolocation API.
//!
//! - ✅ Single and bulk IP lookups (IPv4 and IPv6)
//! - ✅ Works with both the **Free** and **Paid** plans
//! - ✅ HTTPS by default
//! - ✅ Localisation, field selection, threat detection, rate info
//! - ✅ Errors as values — every fallible call returns `Result<_, Error>`
//! - ✅ Uniform error categories (`api`, `network`, `invalid_argument`)
//!
//! ## Quick start
//!
//! ```no_run
//! use ipwhois::{IpWhois, Options};
//!
//! # async fn run() -> Result<(), ipwhois::Error> {
//! // Free plan (no API key, ~1 request/second per client IP)
//! let ipwhois = IpWhois::new();
//! let info = ipwhois.lookup("8.8.8.8").await?;
//!
//! // Paid plan (with API key, higher limits, bulk, security data, …)
//! let ipwhois = IpWhois::with_key("YOUR_API_KEY");
//! let info = ipwhois
//! .lookup_with(
//! "8.8.8.8",
//! &Options::new().with_lang("en").with_security(true),
//! )
//! .await?;
//!
//! // Bulk lookup — up to 100 IPs in one call (paid only)
//! let list = ipwhois
//! .bulk_lookup(["8.8.8.8", "1.1.1.1", "208.67.222.222"])
//! .await?;
//!
//! // HTTPS is enabled by default. Call `.with_ssl(false)` to fall back to HTTP.
//! # Ok(()) }
//! ```
//!
//! ## Error handling
//!
//! Every fallible operation returns [`Result`]`<_, `[`Error`]`>`. The error
//! enum exposes three categories — `api`, `network`, `invalid_argument` —
//! and carries the relevant metadata (`http_status`, plus `retry_after` on
//! free-plan 429s).
//!
//! ```no_run
//! # use ipwhois::{IpWhois, Error};
//! # async fn run() {
//! let ipwhois = IpWhois::new();
//! match ipwhois.lookup("8.8.8.8").await {
//! Ok(info) => println!("{} → {}", info.ip.unwrap_or_default(), info.country.unwrap_or_default()),
//! Err(Error::Api { http_status: Some(429), retry_after, .. }) => {
//! // Rate-limited — `retry_after` is set on the free plan only.
//! eprintln!("rate-limited, retry in {:?}s", retry_after);
//! }
//! Err(e) => eprintln!("Lookup failed ({}): {}", e.error_type(), e.message()),
//! }
//! # }
//! ```
pub use ;
pub use Error;
pub use Options;
pub use ;