yapilt/src/provider.rs
Jan Christian Grünhage 6757ad28f8
initial commit
2020-04-19 15:40:43 +02:00

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()
}
}
}
}