use ffsend_api::url::{ParseError, Url};
use lazy_static::lazy_static;
use regex::Regex;
lazy_static! {
static ref SHORT_SHARE_PATH: Regex =
Regex::new(r"^/dl/([[:alnum:]]{8,}={0,3})/?$").unwrap();
}
pub fn parse_host(host: &str) -> Result<Url, HostError> {
let host = host.trim();
if !host.starts_with("https://") && !host.starts_with("http://") {
return Err(HostError::Scheme);
}
let url = Url::parse(host).map_err(|err| match err {
ParseError::EmptyHost => HostError::Empty,
ParseError::InvalidPort => HostError::Port,
ParseError::InvalidIpv4Address => HostError::Ipv4,
ParseError::InvalidIpv6Address => HostError::Ipv6,
ParseError::InvalidDomainCharacter => HostError::DomainCharacter,
ParseError::RelativeUrlWithoutBase => HostError::NoBase,
err => HostError::Other(err),
})?;
Ok(normalize_share_path(url))
}
pub fn normalize_share_path(mut url: Url) -> Url {
let path = url.path().to_string();
if let Some(caps) = SHORT_SHARE_PATH.captures(&path) {
let id = &caps[1];
url.set_path(&format!("/download/{}/", id));
}
url
}
#[derive(Debug, Fail)]
pub enum HostError {
#[fail(display = "the URL must have the 'https://' or 'http://' scheme")]
Scheme,
#[fail(display = "empty host address")]
Empty,
#[fail(display = "invalid port")]
Port,
#[fail(display = "invalid IPv4 address in the host")]
Ipv4,
#[fail(display = "invalid IPv6 address in the host")]
Ipv6,
#[fail(display = "invalid character in the domain")]
DomainCharacter,
#[fail(display = "missing host in the host URL")]
NoBase,
#[fail(display = "could not parse host URL")]
Other(#[cause] ParseError),
}