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