canihazip/
lib.rs

1//! # CanIHazIP
2//! CanIHazIP gets your current public ip address using [icanhazip](https://icanhazip.com)
3//!
4//! # Example
5//! ```rust
6//! # async fn run() -> Result<(), reqwest::Error> {
7//! let ip = canihazip::plz_ip().await?;
8//! # Ok(())
9//! # }
10//! ```
11
12#[cfg(test)]
13extern crate tokio;
14
15use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
16
17pub type Error = reqwest::Error;
18
19
20/// Get your current public IP address.
21///
22/// Panics if the returned IP is not a valid IP address.
23pub async fn plz_ip() -> Result<IpAddr, Error> {
24    Ok(reqwest::get("https://icanhazip.com/")
25        .await?
26        .text()
27        .await?
28        .trim()
29        .parse::<IpAddr>()
30        .expect("Error parsing IP address"))
31}
32
33/// Get your current public IPv4 address.
34///
35/// Panics if the returned IP is not a valid IPv4 address.
36pub async fn plz_ipv4() -> Result<Ipv4Addr, Error> {
37    Ok(reqwest::get("https://4.icanhazip.com/")
38        .await?
39        .text()
40        .await?
41        .trim()
42        .parse::<Ipv4Addr>()
43        .expect("Error parsing IPv4 address"))
44}
45
46/// Get your current public IPv6 address.
47///
48/// Errors if there is no Ipv6 connectivity.
49/// Panics if the returned IP is not a valid IPv6 address.
50pub async fn plz_ipv6() -> Result<Ipv6Addr, Error> {
51    Ok(reqwest::get("https://6.icanhazip.com/")
52        .await?
53        .text()
54        .await?
55        .trim()
56        .parse::<Ipv6Addr>()
57        .expect("Error parsing IPv6 address"))
58}
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63
64    #[tokio::test]
65    async fn test_plz_ip() {
66        let ip = plz_ip().await.unwrap();
67
68        assert_eq!(ip.is_loopback(), false);
69        assert_eq!(ip.is_unspecified(), false);
70    }
71
72    #[tokio::test]
73    async fn test_plz_ipv4() {
74        let ip = plz_ipv4().await.unwrap();
75
76        assert_eq!(ip.is_private(), false);
77        assert_eq!(ip.is_loopback(), false);
78        assert_eq!(ip.is_link_local(), false);
79        assert_eq!(ip.is_broadcast(), false);
80        assert_eq!(ip.is_documentation(), false);
81        assert_eq!(ip.is_unspecified(), false);
82    }
83
84    #[tokio::test]
85    #[ignore]
86    async fn test_plz_ipv6() {
87        let ip = plz_ipv6().await.unwrap();
88
89        assert_eq!(ip.is_loopback(), false);
90        assert_eq!(ip.is_unspecified(), false);
91        assert_eq!(ip.is_multicast(), false);
92    }
93}