59 lines
1.8 KiB
Rust
59 lines
1.8 KiB
Rust
use crate::{Error, IpType};
|
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
|
pub struct Provider {
|
|
pub v4: Option<&'static str>,
|
|
pub v6: Option<&'static str>,
|
|
}
|
|
|
|
impl Provider {
|
|
pub fn ipify_org() -> Self {
|
|
Self { v4: Some("https://api.ipify.org"), v6: Some("https://api6.ipify.org") }
|
|
}
|
|
|
|
pub fn ident_me() -> Self {
|
|
Self { v4: Some("https://v4.ident.me"), v6: Some("https://v6.ident.me") }
|
|
}
|
|
|
|
pub fn ip(&self, ip_type: IpType) -> Result<http::Request<&'static [u8]>, Error> {
|
|
let uri = match ip_type {
|
|
IpType::V4 => self.v4.ok_or((ip_type, self))?,
|
|
IpType::V6 => self.v6.ok_or((ip_type, self))?,
|
|
};
|
|
Ok(http::Request::get(uri).body(&[][..] as &'static [u8])?)
|
|
}
|
|
}
|
|
|
|
impl Default for Provider {
|
|
fn default() -> Self {
|
|
Self::ident_me()
|
|
}
|
|
}
|
|
|
|
impl std::fmt::Display for Provider {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
|
let provider = match self {
|
|
provider if provider == &Self::ipify_org() => String::from("ipify.org"),
|
|
provider if provider == &Self::ident_me() => String::from("ident.me"),
|
|
_ => String::from("unknown"),
|
|
};
|
|
write!(f, "{}", provider)
|
|
}
|
|
}
|
|
|
|
impl Into<Provider> for String {
|
|
fn into(self) -> Provider {
|
|
match self.as_ref() {
|
|
"ipify.org" => Provider::ipify_org(),
|
|
"ident.me" => Provider::ident_me(),
|
|
provider => {
|
|
// TODO: Handle this better
|
|
// I tried using TryInto here, but I couldn't figure out how to
|
|
// implement From<<T as TryInto<Provider>>::Error>.
|
|
log::error!("Couldn't find provider {}, falling back to the default", provider);
|
|
Provider::default()
|
|
}
|
|
}
|
|
}
|
|
}
|