Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ The free plan is limited to 50,000 requests per month, and doesn't include some
data fields such as the IP type and company information. To get the complete list of
information on an IP address and make more requests per day see [https://ipinfo.io/pricing](https://ipinfo.io/pricing).

⚠️ Note: This library does not currently support our newest free API https://ipinfo.io/lite. If you’d like to use IPinfo Lite, you can call the [endpoint directly](https://ipinfo.io/developers/lite-api) using your preferred HTTP client. Developers are also welcome to contribute support for Lite by submitting a pull request.
The library also supports the Lite API, see the [Lite API section](#lite-api) for more info.

## Examples

Expand Down Expand Up @@ -110,6 +110,42 @@ let config = IpInfoConfig {
};
```

### Lite API

The library gives the possibility to use the [Lite API](https://ipinfo.io/developers/lite-api) too, authentication with your token is still required.

The returned details are slightly different from the Core API.

There's a Lite API example too in the `/examples` directory. You can run it directly like the others, remember to replace `<token>` with your access token

```bash
cargo run --example lookup_lite -- <token>
```

The `lookup_lite` example above looks more or less like

```rust
use ipinfo::{IpInfoLite, IpInfoLiteConfig};
#[tokio::main]
async fn main() {
let config = IpInfoLiteConfig {
token: Some("<token>".to_string()),
..Default::default()
};

let mut ipinfo = IpInfoLite::new(config)
.expect("should construct");

let res = ipinfo.lookup_self_v4().await;
match res {
Ok(r) => {
println!("Current IP lookup result: {:?}", r);
},
Err(e) => println!("error occurred: {}", &e.to_string()),
}
}
```

## Other Libraries

There are official IPinfo client libraries available for many languages including
Expand Down
22 changes: 22 additions & 0 deletions examples/lookup_lite.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use ipinfo::{IpInfoLite, IpInfoLiteConfig};
use std::env;

#[tokio::main]
async fn main() {
let token = env::args().nth(1);

let config = IpInfoLiteConfig {
token,
..Default::default()
};

let mut ipinfo = IpInfoLite::new(config).expect("should construct");

let res = ipinfo.lookup_self_v4().await;
match res {
Ok(r) => {
println!("Current IP lookup result: {:?}", r);
}
Err(e) => println!("error occurred: {}", &e.to_string()),
}
}
56 changes: 53 additions & 3 deletions src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,22 +197,72 @@ pub struct DomainsDetails {
}

/// CountryFlag details.
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq)]
pub struct CountryFlag {
pub emoji: String,
pub unicode: String,
}

/// CountryCurrency details.
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq)]
pub struct CountryCurrency {
pub code: String,
pub symbol: String,
}

/// Continent details.
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq)]
#[derive(Debug, Default, Deserialize, Serialize, Clone, PartialEq)]
pub struct Continent {
pub code: String,
pub name: String,
}

#[derive(Debug, Default, Deserialize, Serialize, Clone)]
pub struct IpDetailsLite {
pub ip: String,

/// The country code for the IP address.
pub country_code: String,

/// The country name for the IP address.
pub country: String,

/// The country name for the IP address.
#[serde(skip_deserializing)]
pub country_name: String,

/// EU status of the country.
#[serde(skip_deserializing)]
pub is_eu: bool,

/// Flag and unicode of the country.
#[serde(skip_deserializing)]
pub country_flag: CountryFlag,

/// Link of the Flag of country.
#[serde(skip_deserializing)]
pub country_flag_url: String,

/// Code and symbol of the country's currency.
#[serde(skip_deserializing)]
pub country_currency: CountryCurrency,

/// The AS number.
pub asn: String,

/// The AS name.
pub as_name: String,

/// The AS domain.
pub as_domain: String,

/// Code and name of the continent.
#[serde(skip_deserializing)]
pub continent: Continent,

/// If the IP Address is Bogon
pub bogon: Option<bool>,

#[serde(flatten)]
pub extra: HashMap<String, Value>,
}
2 changes: 1 addition & 1 deletion src/bogon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ lazy_static! {
/// assert_eq!(is_bogon("foo"), false);
/// ```
pub fn is_bogon(ip_address: &str) -> bool {
ip_address.parse().map_or(false, is_bogon_addr)
ip_address.parse().is_ok_and(is_bogon_addr)
}

/// Returns a boolean indicating whether an IP address is bogus.
Expand Down
18 changes: 9 additions & 9 deletions src/ipinfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ impl IpInfo {
) -> Result<HashMap<String, IpDetails>, IpError> {
// Lookup cache misses which are not bogon
let response = client
.post(format!("{}/batch", BASE_URL))
.post(format!("{BASE_URL}/batch"))
.headers(Self::construct_headers())
.bearer_auth(self.token.as_deref().unwrap_or_default())
.json(&json!(ips))
Expand Down Expand Up @@ -363,7 +363,7 @@ impl IpInfo {
// lookup in case of a cache miss
let response = self
.client
.get(format!("{}/{}", base_url, ip))
.get(format!("{base_url}/{ip}"))
.headers(Self::construct_headers())
.bearer_auth(self.token.as_deref().unwrap_or_default())
.send()
Expand Down Expand Up @@ -412,7 +412,7 @@ impl IpInfo {
return Err(err!(MapLimitError));
}

let map_url = &format!("{}/tools/map?cli=1", BASE_URL);
let map_url = &format!("{BASE_URL}/tools/map?cli=1");
let client = self.client.clone();
let json_ips = serde_json::json!(ips);

Expand Down Expand Up @@ -454,7 +454,7 @@ impl IpInfo {
let mut headers = HeaderMap::new();
headers.insert(
USER_AGENT,
HeaderValue::from_str(&format!("IPinfoClient/Rust/{}", VERSION))
HeaderValue::from_str(&format!("IPinfoClient/Rust/{VERSION}"))
.unwrap(),
);
headers.insert(
Expand Down Expand Up @@ -584,12 +584,12 @@ mod tests {
let ip4 = &details["4.2.2.4"];
assert_eq!(ip4.ip, "4.2.2.4");
assert_eq!(ip4.hostname, Some("d.resolvers.level3.net".to_owned()));
assert_eq!(ip4.city, "Broomfield");
assert_eq!(ip4.region, "Colorado");
assert_eq!(ip4.city, "Monroe");
assert_eq!(ip4.region, "Louisiana");
assert_eq!(ip4.country, "US");
assert_eq!(ip4.loc, "39.8854,-105.1139");
assert_eq!(ip4.postal, Some("80021".to_owned()));
assert_eq!(ip4.timezone, Some("America/Denver".to_owned()));
assert_eq!(ip4.loc, "32.5530,-92.0422");
assert_eq!(ip4.postal, Some("71203".to_owned()));
assert_eq!(ip4.timezone, Some("America/Chicago".to_owned()));
}

#[tokio::test]
Expand Down
Loading